refactor a good bit of stuff for better dependency injection
fix regular expression for T6 log parsing
This commit is contained in:
parent
ec053eb854
commit
c3c21a7749
@ -58,11 +58,12 @@ namespace IW4MAdmin.Application
|
|||||||
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 readonly ITranslationLookup _translationLookup;
|
private readonly ITranslationLookup _translationLookup;
|
||||||
private readonly IConfigurationHandler<CommandConfiguration> _commandConfiguration;
|
private readonly IConfigurationHandler<CommandConfiguration> _commandConfiguration;
|
||||||
private readonly IPluginImporter _pluginImporter;
|
private readonly IGameServerInstanceFactory _serverInstanceFactory;
|
||||||
|
|
||||||
public ApplicationManager(ILogger logger, IMiddlewareActionHandler actionHandler, IEnumerable<IManagerCommand> commands,
|
public ApplicationManager(ILogger logger, IMiddlewareActionHandler actionHandler, IEnumerable<IManagerCommand> commands,
|
||||||
ITranslationLookup translationLookup, IConfigurationHandler<CommandConfiguration> commandConfiguration,
|
ITranslationLookup translationLookup, IConfigurationHandler<CommandConfiguration> commandConfiguration,
|
||||||
IConfigurationHandler<ApplicationConfiguration> appConfigHandler, IPluginImporter pluginImporter)
|
IConfigurationHandler<ApplicationConfiguration> appConfigHandler, IGameServerInstanceFactory serverInstanceFactory,
|
||||||
|
IEnumerable<IPlugin> plugins)
|
||||||
{
|
{
|
||||||
MiddlewareActionHandler = actionHandler;
|
MiddlewareActionHandler = actionHandler;
|
||||||
_servers = new ConcurrentBag<Server>();
|
_servers = new ConcurrentBag<Server>();
|
||||||
@ -73,8 +74,8 @@ namespace IW4MAdmin.Application
|
|||||||
ConfigHandler = appConfigHandler;
|
ConfigHandler = appConfigHandler;
|
||||||
StartTime = DateTime.UtcNow;
|
StartTime = DateTime.UtcNow;
|
||||||
PageList = new PageList();
|
PageList = new PageList();
|
||||||
AdditionalEventParsers = new List<IEventParser>();
|
AdditionalEventParsers = new List<IEventParser>() { new BaseEventParser() };
|
||||||
AdditionalRConParsers = new List<IRConParser>();
|
AdditionalRConParsers = new List<IRConParser>() { new BaseRConParser() };
|
||||||
TokenAuthenticator = new TokenAuthentication();
|
TokenAuthenticator = new TokenAuthentication();
|
||||||
_metaService = new MetaService();
|
_metaService = new MetaService();
|
||||||
_tokenSource = new CancellationTokenSource();
|
_tokenSource = new CancellationTokenSource();
|
||||||
@ -82,9 +83,12 @@ namespace IW4MAdmin.Application
|
|||||||
_commands = commands.ToList();
|
_commands = commands.ToList();
|
||||||
_translationLookup = translationLookup;
|
_translationLookup = translationLookup;
|
||||||
_commandConfiguration = commandConfiguration;
|
_commandConfiguration = commandConfiguration;
|
||||||
_pluginImporter = pluginImporter;
|
_serverInstanceFactory = serverInstanceFactory;
|
||||||
|
Plugins = plugins;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IEnumerable<IPlugin> Plugins { get; }
|
||||||
|
|
||||||
public async Task ExecuteEvent(GameEvent newEvent)
|
public async Task ExecuteEvent(GameEvent newEvent)
|
||||||
{
|
{
|
||||||
#if DEBUG == true
|
#if DEBUG == true
|
||||||
@ -249,7 +253,7 @@ namespace IW4MAdmin.Application
|
|||||||
ExternalIPAddress = await Utilities.GetExternalIP();
|
ExternalIPAddress = await Utilities.GetExternalIP();
|
||||||
|
|
||||||
#region PLUGINS
|
#region PLUGINS
|
||||||
foreach (var plugin in _pluginImporter.ActivePlugins)
|
foreach (var plugin in Plugins)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -567,7 +571,8 @@ namespace IW4MAdmin.Application
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var ServerInstance = new IW4MServer(this, Conf, _translationLookup, _pluginImporter);
|
// todo: this might not always be an IW4MServer
|
||||||
|
var ServerInstance = _serverInstanceFactory.CreateServer(Conf, this) as IW4MServer;
|
||||||
await ServerInstance.Initialize();
|
await ServerInstance.Initialize();
|
||||||
|
|
||||||
_servers.Add(ServerInstance);
|
_servers.Add(ServerInstance);
|
||||||
@ -759,11 +764,6 @@ namespace IW4MAdmin.Application
|
|||||||
return Handler;
|
return Handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IList<Assembly> GetPluginAssemblies()
|
|
||||||
{
|
|
||||||
return _pluginImporter.PluginAssemblies.Union(_pluginImporter.Assemblies).ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
public IPageList GetPageList()
|
public IPageList GetPageList()
|
||||||
{
|
{
|
||||||
return PageList;
|
return PageList;
|
||||||
|
@ -9,7 +9,7 @@ using static SharedLibraryCore.Server;
|
|||||||
|
|
||||||
namespace IW4MAdmin.Application.EventParsers
|
namespace IW4MAdmin.Application.EventParsers
|
||||||
{
|
{
|
||||||
class BaseEventParser : IEventParser
|
public class BaseEventParser : IEventParser
|
||||||
{
|
{
|
||||||
public BaseEventParser()
|
public BaseEventParser()
|
||||||
{
|
{
|
||||||
@ -37,7 +37,7 @@ namespace IW4MAdmin.Application.EventParsers
|
|||||||
Configuration.Join.AddMapping(ParserRegex.GroupType.OriginClientNumber, 3);
|
Configuration.Join.AddMapping(ParserRegex.GroupType.OriginClientNumber, 3);
|
||||||
Configuration.Join.AddMapping(ParserRegex.GroupType.OriginName, 4);
|
Configuration.Join.AddMapping(ParserRegex.GroupType.OriginName, 4);
|
||||||
|
|
||||||
Configuration.Damage.Pattern = @"^(D);(-?[A-Fa-f0-9_]{1,32}|bot[0-9]+);(-?[0-9]+);(axis|allies|world)?;(.{1,24});(-?[A-Fa-f0-9_]{1,32}|bot[0-9]+)?;-?([0-9]+);(axis|allies|world)?;(.{1,24})?;((?:[0-9]+|[a-z]+|_)+);([0-9]+);((?:[A-Z]|_)+);((?:[a-z]|_)+)$";
|
Configuration.Damage.Pattern = @"^(D);(-?[A-Fa-f0-9_]{1,32}|bot[0-9]+);(-?[0-9]+);(axis|allies|world)?;([^;]{1,24});(-?[A-Fa-f0-9_]{1,32}|bot[0-9]+)?;-?([0-9]+);(axis|allies|world)?;([^;]{1,24})?;((?:[0-9]+|[a-z]+|_|\+)+);([0-9]+);((?:[A-Z]|_)+);((?:[a-z]|_)+)$";
|
||||||
Configuration.Damage.AddMapping(ParserRegex.GroupType.EventType, 1);
|
Configuration.Damage.AddMapping(ParserRegex.GroupType.EventType, 1);
|
||||||
Configuration.Damage.AddMapping(ParserRegex.GroupType.TargetNetworkId, 2);
|
Configuration.Damage.AddMapping(ParserRegex.GroupType.TargetNetworkId, 2);
|
||||||
Configuration.Damage.AddMapping(ParserRegex.GroupType.TargetClientNumber, 3);
|
Configuration.Damage.AddMapping(ParserRegex.GroupType.TargetClientNumber, 3);
|
||||||
@ -52,7 +52,7 @@ namespace IW4MAdmin.Application.EventParsers
|
|||||||
Configuration.Damage.AddMapping(ParserRegex.GroupType.MeansOfDeath, 12);
|
Configuration.Damage.AddMapping(ParserRegex.GroupType.MeansOfDeath, 12);
|
||||||
Configuration.Damage.AddMapping(ParserRegex.GroupType.HitLocation, 13);
|
Configuration.Damage.AddMapping(ParserRegex.GroupType.HitLocation, 13);
|
||||||
|
|
||||||
Configuration.Kill.Pattern = @"^(K);(-?[A-Fa-f0-9_]{1,32}|bot[0-9]+);(-?[0-9]+);(axis|allies|world)?;(.{1,24});(-?[A-Fa-f0-9_]{1,32}|bot[0-9]+)?;-?([0-9]+);(axis|allies|world)?;(.{1,24})?;((?:[0-9]+|[a-z]+|_)+);([0-9]+);((?:[A-Z]|_)+);((?:[a-z]|_)+)$";
|
Configuration.Kill.Pattern = @"^(K);(-?[A-Fa-f0-9_]{1,32}|bot[0-9]+);(-?[0-9]+);(axis|allies|world)?;([^;]{1,24});(-?[A-Fa-f0-9_]{1,32}|bot[0-9]+)?;-?([0-9]+);(axis|allies|world)?;([^;]{1,24})?;((?:[0-9]+|[a-z]+|_|\+)+);([0-9]+);((?:[A-Z]|_)+);((?:[a-z]|_)+)$";
|
||||||
Configuration.Kill.AddMapping(ParserRegex.GroupType.EventType, 1);
|
Configuration.Kill.AddMapping(ParserRegex.GroupType.EventType, 1);
|
||||||
Configuration.Kill.AddMapping(ParserRegex.GroupType.TargetNetworkId, 2);
|
Configuration.Kill.AddMapping(ParserRegex.GroupType.TargetNetworkId, 2);
|
||||||
Configuration.Kill.AddMapping(ParserRegex.GroupType.TargetClientNumber, 3);
|
Configuration.Kill.AddMapping(ParserRegex.GroupType.TargetClientNumber, 3);
|
||||||
|
23
Application/Factories/ConfigurationHandlerFactory.cs
Normal file
23
Application/Factories/ConfigurationHandlerFactory.cs
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
using IW4MAdmin.Application.Misc;
|
||||||
|
using SharedLibraryCore.Interfaces;
|
||||||
|
|
||||||
|
namespace IW4MAdmin.Application.Factories
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// implementation of IConfigurationHandlerFactory
|
||||||
|
/// provides base functionality to create configuration handlers
|
||||||
|
/// </summary>
|
||||||
|
public class ConfigurationHandlerFactory : IConfigurationHandlerFactory
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// creates a base configuration handler
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">base configuration type</typeparam>
|
||||||
|
/// <param name="name">name of the config file</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public IConfigurationHandler<T> GetConfigurationHandler<T>(string name) where T : IBaseConfiguration
|
||||||
|
{
|
||||||
|
return new BaseConfigurationHandler<T>(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
38
Application/Factories/GameServerInstanceFactory.cs
Normal file
38
Application/Factories/GameServerInstanceFactory.cs
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
using SharedLibraryCore;
|
||||||
|
using SharedLibraryCore.Configuration;
|
||||||
|
using SharedLibraryCore.Interfaces;
|
||||||
|
using System.Collections;
|
||||||
|
|
||||||
|
namespace IW4MAdmin.Application.Factories
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// implementation of IGameServerInstanceFactory
|
||||||
|
/// </summary>
|
||||||
|
internal class GameServerInstanceFactory : IGameServerInstanceFactory
|
||||||
|
{
|
||||||
|
private readonly ITranslationLookup _translationLookup;
|
||||||
|
private readonly IRConConnectionFactory _rconConnectionFactory;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// base constructor
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="translationLookup"></param>
|
||||||
|
/// <param name="rconConnectionFactory"></param>
|
||||||
|
public GameServerInstanceFactory(ITranslationLookup translationLookup, IRConConnectionFactory rconConnectionFactory)
|
||||||
|
{
|
||||||
|
_translationLookup = translationLookup;
|
||||||
|
_rconConnectionFactory = rconConnectionFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// creates an IW4MServer instance
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="config">server configuration</param>
|
||||||
|
/// <param name="manager">application manager</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public Server CreateServer(ServerConfiguration config, IManager manager)
|
||||||
|
{
|
||||||
|
return new IW4MServer(manager, config, _translationLookup, _rconConnectionFactory);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
36
Application/Factories/RConConnectionFactory.cs
Normal file
36
Application/Factories/RConConnectionFactory.cs
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
using IW4MAdmin.Application.RCon;
|
||||||
|
using SharedLibraryCore.Interfaces;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace IW4MAdmin.Application.Factories
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// implementation of IRConConnectionFactory
|
||||||
|
/// </summary>
|
||||||
|
internal class RConConnectionFactory : IRConConnectionFactory
|
||||||
|
{
|
||||||
|
private static readonly Encoding gameEncoding = Encoding.GetEncoding("windows-1252");
|
||||||
|
private readonly ILogger _logger;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Base constructor
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="logger"></param>
|
||||||
|
public RConConnectionFactory(ILogger logger)
|
||||||
|
{
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// creates a new rcon connection instance
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="ipAddress">ip address of the server</param>
|
||||||
|
/// <param name="port">port of the server</param>
|
||||||
|
/// <param name="password">rcon password of the server</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public IRConConnection CreateConnection(string ipAddress, int port, string password)
|
||||||
|
{
|
||||||
|
return new RConConnection(ipAddress, port, password, _logger, gameEncoding);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -27,15 +27,14 @@ namespace IW4MAdmin
|
|||||||
private GameLogEventDetection LogEvent;
|
private GameLogEventDetection LogEvent;
|
||||||
private readonly ITranslationLookup _translationLookup;
|
private readonly ITranslationLookup _translationLookup;
|
||||||
private const int REPORT_FLAG_COUNT = 4;
|
private const int REPORT_FLAG_COUNT = 4;
|
||||||
private readonly IPluginImporter _pluginImporter;
|
|
||||||
private int lastGameTime = 0;
|
private int lastGameTime = 0;
|
||||||
|
|
||||||
public int Id { get; private set; }
|
public int Id { get; private set; }
|
||||||
|
|
||||||
public IW4MServer(IManager mgr, ServerConfiguration cfg, ITranslationLookup lookup, IPluginImporter pluginImporter) : base(mgr, cfg)
|
public IW4MServer(IManager mgr, ServerConfiguration cfg, ITranslationLookup lookup,
|
||||||
|
IRConConnectionFactory connectionFactory) : base(mgr, connectionFactory, cfg)
|
||||||
{
|
{
|
||||||
_translationLookup = lookup;
|
_translationLookup = lookup;
|
||||||
_pluginImporter = pluginImporter;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override public async Task<EFClient> OnClientConnected(EFClient clientFromLog)
|
override public async Task<EFClient> OnClientConnected(EFClient clientFromLog)
|
||||||
@ -66,6 +65,7 @@ namespace IW4MAdmin
|
|||||||
client.Score = clientFromLog.Score;
|
client.Score = clientFromLog.Score;
|
||||||
client.Ping = clientFromLog.Ping;
|
client.Ping = clientFromLog.Ping;
|
||||||
client.CurrentServer = this;
|
client.CurrentServer = this;
|
||||||
|
client.State = ClientState.Connecting;
|
||||||
|
|
||||||
Clients[client.ClientNumber] = client;
|
Clients[client.ClientNumber] = client;
|
||||||
#if DEBUG == true
|
#if DEBUG == true
|
||||||
@ -153,7 +153,7 @@ namespace IW4MAdmin
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var plugin in _pluginImporter.ActivePlugins)
|
foreach (var plugin in Manager.Plugins)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -182,6 +182,11 @@ namespace IW4MAdmin
|
|||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
lastException = e;
|
lastException = e;
|
||||||
|
|
||||||
|
if (E.Origin != null)
|
||||||
|
{
|
||||||
|
E.Origin.Tell(_translationLookup["SERVER_ERROR_COMMAND_INGAME"]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
finally
|
finally
|
||||||
@ -695,7 +700,7 @@ namespace IW4MAdmin
|
|||||||
await e.WaitAsync(Utilities.DefaultCommandTimeout, new CancellationTokenRegistration().Token);
|
await e.WaitAsync(Utilities.DefaultCommandTimeout, new CancellationTokenRegistration().Token);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var plugin in _pluginImporter.ActivePlugins)
|
foreach (var plugin in Manager.Plugins)
|
||||||
{
|
{
|
||||||
await plugin.OnUnloadAsync();
|
await plugin.OnUnloadAsync();
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
using IW4MAdmin.Application.Helpers;
|
using IW4MAdmin.Application.Factories;
|
||||||
|
using IW4MAdmin.Application.Helpers;
|
||||||
|
using IW4MAdmin.Application.IO;
|
||||||
using IW4MAdmin.Application.Migration;
|
using IW4MAdmin.Application.Migration;
|
||||||
using IW4MAdmin.Application.Misc;
|
using IW4MAdmin.Application.Misc;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
@ -8,7 +10,6 @@ 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;
|
||||||
@ -266,27 +267,21 @@ namespace IW4MAdmin.Application
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private static IServiceCollection ConfigureServices()
|
private static IServiceCollection ConfigureServices()
|
||||||
{
|
{
|
||||||
|
var defaultLogger = new Logger("IW4MAdmin-Manager");
|
||||||
|
var pluginImporter = new PluginImporter(defaultLogger);
|
||||||
|
|
||||||
var serviceCollection = new ServiceCollection();
|
var serviceCollection = new ServiceCollection();
|
||||||
serviceCollection.AddSingleton<IServiceCollection>(_serviceProvider => serviceCollection)
|
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())
|
||||||
.AddSingleton(_serviceProvider => _serviceProvider.GetRequiredService<IConfigurationHandler<CommandConfiguration>>().Configuration() ?? new CommandConfiguration())
|
.AddSingleton(_serviceProvider => _serviceProvider.GetRequiredService<IConfigurationHandler<CommandConfiguration>>().Configuration() ?? new CommandConfiguration())
|
||||||
.AddSingleton<ILogger>(_serviceProvider => new Logger("IW4MAdmin-Manager"))
|
.AddSingleton<ILogger>(_serviceProvider => defaultLogger)
|
||||||
.AddSingleton<IPluginImporter, PluginImporter>()
|
.AddSingleton<IPluginImporter, PluginImporter>()
|
||||||
.AddSingleton<IMiddlewareActionHandler, MiddlewareActionHandler>()
|
.AddSingleton<IMiddlewareActionHandler, MiddlewareActionHandler>()
|
||||||
.AddTransient(_serviceProvider =>
|
.AddSingleton<IRConConnectionFactory, RConConnectionFactory>()
|
||||||
{
|
.AddSingleton<IGameServerInstanceFactory, GameServerInstanceFactory>()
|
||||||
var importer = _serviceProvider.GetRequiredService<IPluginImporter>();
|
.AddSingleton<IConfigurationHandlerFactory, ConfigurationHandlerFactory>()
|
||||||
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();
|
||||||
@ -295,6 +290,35 @@ namespace IW4MAdmin.Application
|
|||||||
})
|
})
|
||||||
.AddSingleton<IManager, ApplicationManager>();
|
.AddSingleton<IManager, ApplicationManager>();
|
||||||
|
|
||||||
|
// register the native commands
|
||||||
|
foreach (var commandType in typeof(SharedLibraryCore.Commands.QuitCommand).Assembly.GetTypes()
|
||||||
|
.Where(_command => _command.BaseType == typeof(Command)))
|
||||||
|
{
|
||||||
|
defaultLogger.WriteInfo($"Registered native command type {commandType.Name}");
|
||||||
|
serviceCollection.AddSingleton(typeof(IManagerCommand), commandType);
|
||||||
|
}
|
||||||
|
|
||||||
|
// register the plugin implementations
|
||||||
|
var pluginImplementations = pluginImporter.DiscoverAssemblyPluginImplementations();
|
||||||
|
foreach (var pluginType in pluginImplementations.Item1)
|
||||||
|
{
|
||||||
|
defaultLogger.WriteInfo($"Registered plugin type {pluginType.FullName}");
|
||||||
|
serviceCollection.AddSingleton(typeof(IPlugin), pluginType);
|
||||||
|
}
|
||||||
|
|
||||||
|
// register the plugin commands
|
||||||
|
foreach (var commandType in pluginImplementations.Item2)
|
||||||
|
{
|
||||||
|
defaultLogger.WriteInfo($"Registered plugin command type {commandType.FullName}");
|
||||||
|
serviceCollection.AddSingleton(typeof(IManagerCommand), commandType);
|
||||||
|
}
|
||||||
|
|
||||||
|
// register any script plugins
|
||||||
|
foreach (var scriptPlugin in pluginImporter.DiscoverScriptPlugins())
|
||||||
|
{
|
||||||
|
serviceCollection.AddSingleton(scriptPlugin);
|
||||||
|
}
|
||||||
|
|
||||||
return serviceCollection;
|
return serviceCollection;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,11 @@ namespace IW4MAdmin.Application.Migration
|
|||||||
{
|
{
|
||||||
Directory.CreateDirectory(Path.Join(Utilities.OperatingDirectory, "Log"));
|
Directory.CreateDirectory(Path.Join(Utilities.OperatingDirectory, "Log"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!Directory.Exists(Path.Join(Utilities.OperatingDirectory, "Localization")))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(Path.Join(Utilities.OperatingDirectory, "Localization"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -1,12 +1,17 @@
|
|||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
using SharedLibraryCore;
|
||||||
using SharedLibraryCore.Exceptions;
|
using SharedLibraryCore.Exceptions;
|
||||||
using SharedLibraryCore.Interfaces;
|
using SharedLibraryCore.Interfaces;
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace SharedLibraryCore.Configuration
|
namespace IW4MAdmin.Application.Misc
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// default implementation of IConfigurationHandler
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">base configuration type</typeparam>
|
||||||
public class BaseConfigurationHandler<T> : IConfigurationHandler<T> where T : IBaseConfiguration
|
public class BaseConfigurationHandler<T> : IConfigurationHandler<T> where T : IBaseConfiguration
|
||||||
{
|
{
|
||||||
T _configuration;
|
T _configuration;
|
@ -1,12 +1,14 @@
|
|||||||
using SharedLibraryCore;
|
using IW4MAdmin.Application.IO;
|
||||||
|
using SharedLibraryCore;
|
||||||
using SharedLibraryCore.Interfaces;
|
using SharedLibraryCore.Interfaces;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
|
||||||
namespace IW4MAdmin.Application
|
namespace IW4MAdmin.Application
|
||||||
{
|
{
|
||||||
class Logger : ILogger
|
public class Logger : ILogger
|
||||||
{
|
{
|
||||||
enum LogType
|
enum LogType
|
||||||
{
|
{
|
||||||
@ -77,9 +79,7 @@ namespace IW4MAdmin.Application
|
|||||||
{
|
{
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
// lets keep it simple and dispose of everything quickly as logging wont be that much (relatively)
|
// lets keep it simple and dispose of everything quickly as logging wont be that much (relatively)
|
||||||
Console.WriteLine(LogLine);
|
Console.WriteLine(msg);
|
||||||
//File.AppendAllText(FileName, $"{LogLine}{Environment.NewLine}");
|
|
||||||
//Debug.WriteLine(msg);
|
|
||||||
#else
|
#else
|
||||||
if (type == LogType.Error || type == LogType.Verbose)
|
if (type == LogType.Error || type == LogType.Verbose)
|
||||||
{
|
{
|
||||||
|
@ -5,111 +5,84 @@ using System.Reflection;
|
|||||||
using SharedLibraryCore.Interfaces;
|
using SharedLibraryCore.Interfaces;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using SharedLibraryCore;
|
using SharedLibraryCore;
|
||||||
|
using IW4MAdmin.Application.Misc;
|
||||||
|
|
||||||
namespace IW4MAdmin.Application.Helpers
|
namespace IW4MAdmin.Application.Helpers
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// implementation of IPluginImporter
|
||||||
|
/// discovers plugins and script plugins
|
||||||
|
/// </summary>
|
||||||
public class PluginImporter : IPluginImporter
|
public class PluginImporter : IPluginImporter
|
||||||
{
|
{
|
||||||
public IList<Type> CommandTypes { get; private set; } = new List<Type>();
|
private static readonly string PLUGIN_DIR = "Plugins";
|
||||||
public IList<IPlugin> ActivePlugins { get; private set; } = new List<IPlugin>();
|
|
||||||
public IList<Assembly> PluginAssemblies { get; private set; } = new List<Assembly>();
|
|
||||||
public IList<Assembly> Assemblies { get; private set; } = new List<Assembly>();
|
|
||||||
|
|
||||||
private readonly ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
private readonly ITranslationLookup _translationLookup;
|
|
||||||
|
|
||||||
public PluginImporter(ILogger logger, ITranslationLookup translationLookup)
|
public PluginImporter(ILogger logger)
|
||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_translationLookup = translationLookup;
|
|
||||||
|
|
||||||
Load();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Loads all the assembly and javascript plugins
|
/// discovers all the script plugins in the plugins dir
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void Load()
|
/// <returns></returns>
|
||||||
|
public IEnumerable<IPlugin> DiscoverScriptPlugins()
|
||||||
{
|
{
|
||||||
string pluginDir = $"{Utilities.OperatingDirectory}Plugins{Path.DirectorySeparatorChar}";
|
string pluginDir = $"{Utilities.OperatingDirectory}{PLUGIN_DIR}{Path.DirectorySeparatorChar}";
|
||||||
string[] dllFileNames = null;
|
|
||||||
string[] scriptFileNames = null;
|
|
||||||
|
|
||||||
if (Directory.Exists(pluginDir))
|
if (Directory.Exists(pluginDir))
|
||||||
{
|
{
|
||||||
dllFileNames = Directory.GetFiles($"{Utilities.OperatingDirectory}Plugins{Path.DirectorySeparatorChar}", "*.dll");
|
string[] scriptPluginFiles = Directory.GetFiles(pluginDir, "*.js");
|
||||||
scriptFileNames = Directory.GetFiles($"{Utilities.OperatingDirectory}Plugins{Path.DirectorySeparatorChar}", "*.js");
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
_logger.WriteInfo($"Discovered {scriptPluginFiles.Length} potential script plugins");
|
||||||
{
|
|
||||||
dllFileNames = new string[0];
|
|
||||||
scriptFileNames = new string[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dllFileNames.Length == 0 &&
|
if (scriptPluginFiles.Length > 0)
|
||||||
scriptFileNames.Length == 0)
|
|
||||||
{
|
{
|
||||||
_logger.WriteDebug(_translationLookup["PLUGIN_IMPORTER_NOTFOUND"]);
|
foreach (string fileName in scriptPluginFiles)
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// load up the script plugins
|
|
||||||
foreach (string fileName in scriptFileNames)
|
|
||||||
{
|
{
|
||||||
|
_logger.WriteInfo($"Discovered script plugin {fileName}");
|
||||||
var plugin = new ScriptPlugin(fileName);
|
var plugin = new ScriptPlugin(fileName);
|
||||||
_logger.WriteDebug($"Loaded script plugin \"{ plugin.Name }\" [{plugin.Version}]");
|
yield return plugin;
|
||||||
ActivePlugins.Add(plugin);
|
|
||||||
}
|
|
||||||
|
|
||||||
ICollection<Assembly> assemblies = new List<Assembly>(dllFileNames.Length);
|
|
||||||
foreach (string dllFile in dllFileNames)
|
|
||||||
{
|
|
||||||
assemblies.Add(Assembly.LoadFrom(dllFile));
|
|
||||||
}
|
|
||||||
|
|
||||||
int LoadedCommands = 0;
|
|
||||||
foreach (Assembly Plugin in assemblies)
|
|
||||||
{
|
|
||||||
if (Plugin != null)
|
|
||||||
{
|
|
||||||
Assemblies.Add(Plugin);
|
|
||||||
Type[] types = Plugin.GetTypes();
|
|
||||||
foreach (Type assemblyType in types)
|
|
||||||
{
|
|
||||||
if (assemblyType.IsClass && assemblyType.BaseType == typeof(Command))
|
|
||||||
{
|
|
||||||
CommandTypes.Add(assemblyType);
|
|
||||||
_logger.WriteDebug($"{_translationLookup["PLUGIN_IMPORTER_REGISTERCMD"]} \"{assemblyType.Name}\"");
|
|
||||||
LoadedCommands++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (assemblyType.GetInterface("IPlugin", false) == null)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
var notifyObject = Activator.CreateInstance(assemblyType);
|
|
||||||
IPlugin newNotify = (IPlugin)notifyObject;
|
|
||||||
if (ActivePlugins.FirstOrDefault(x => x.Name == newNotify.Name) == null)
|
|
||||||
{
|
|
||||||
ActivePlugins.Add(newNotify);
|
|
||||||
PluginAssemblies.Add(Plugin);
|
|
||||||
_logger.WriteDebug($"Loaded plugin \"{newNotify.Name}\" [{newNotify.Version}]");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
_logger.WriteWarning(_translationLookup["PLUGIN_IMPORTER_ERROR"].FormatExt(Plugin.Location));
|
|
||||||
_logger.WriteDebug(e.GetExceptionInfo());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_logger.WriteInfo($"Loaded {ActivePlugins.Count} plugins and registered {LoadedCommands} plugin commands.");
|
/// <summary>
|
||||||
|
/// discovers all the C# assembly plugins and commands
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public (IEnumerable<Type>, IEnumerable<Type>) DiscoverAssemblyPluginImplementations()
|
||||||
|
{
|
||||||
|
string pluginDir = $"{Utilities.OperatingDirectory}{PLUGIN_DIR}{Path.DirectorySeparatorChar}";
|
||||||
|
var pluginTypes = Enumerable.Empty<Type>();
|
||||||
|
var commandTypes = Enumerable.Empty<Type>();
|
||||||
|
|
||||||
|
if (Directory.Exists(pluginDir))
|
||||||
|
{
|
||||||
|
var dllFileNames = Directory.GetFiles(pluginDir, "*.dll");
|
||||||
|
_logger.WriteInfo($"Discovered {dllFileNames.Length} potential plugin assemblies");
|
||||||
|
|
||||||
|
if (dllFileNames.Length > 0)
|
||||||
|
{
|
||||||
|
var assemblies = dllFileNames.Select(_name => Assembly.LoadFrom(_name));
|
||||||
|
|
||||||
|
pluginTypes = assemblies
|
||||||
|
.SelectMany(_asm => _asm.GetTypes())
|
||||||
|
.Where(_assemblyType => _assemblyType.GetInterface(nameof(IPlugin), false) != null);
|
||||||
|
|
||||||
|
_logger.WriteInfo($"Discovered {pluginTypes.Count()} plugin implementations");
|
||||||
|
|
||||||
|
commandTypes = assemblies
|
||||||
|
.SelectMany(_asm => _asm.GetTypes())
|
||||||
|
.Where(_assemblyType => _assemblyType.IsClass && _assemblyType.BaseType == typeof(Command));
|
||||||
|
|
||||||
|
_logger.WriteInfo($"Discovered {commandTypes.Count()} plugin commands");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (pluginTypes, commandTypes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,19 @@
|
|||||||
using Jint;
|
using Jint;
|
||||||
|
using SharedLibraryCore;
|
||||||
using SharedLibraryCore.Database.Models;
|
using SharedLibraryCore.Database.Models;
|
||||||
using SharedLibraryCore.Interfaces;
|
using SharedLibraryCore.Interfaces;
|
||||||
using System;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace SharedLibraryCore
|
namespace IW4MAdmin.Application.Misc
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// implementation of IPlugin
|
||||||
|
/// used to proxy script plugin requests
|
||||||
|
/// </summary>
|
||||||
public class ScriptPlugin : IPlugin
|
public class ScriptPlugin : IPlugin
|
||||||
{
|
{
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
@ -45,7 +49,6 @@ namespace SharedLibraryCore
|
|||||||
_onProcessing.Dispose();
|
_onProcessing.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public async Task Initialize(IManager manager)
|
public async Task Initialize(IManager manager)
|
||||||
{
|
{
|
||||||
await _onProcessing.WaitAsync();
|
await _onProcessing.WaitAsync();
|
29
Application/RCon/ConnectionState.cs
Normal file
29
Application/RCon/ConnectionState.cs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
using System;
|
||||||
|
using System.Net.Sockets;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
|
namespace IW4MAdmin.Application.RCon
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// used to keep track of the udp connection state
|
||||||
|
/// </summary>
|
||||||
|
internal class ConnectionState
|
||||||
|
{
|
||||||
|
~ConnectionState()
|
||||||
|
{
|
||||||
|
OnComplete.Dispose();
|
||||||
|
OnSentData.Dispose();
|
||||||
|
OnReceivedData.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int ConnectionAttempts { get; set; }
|
||||||
|
const int BufferSize = 4096;
|
||||||
|
public readonly byte[] ReceiveBuffer = new byte[BufferSize];
|
||||||
|
public readonly SemaphoreSlim OnComplete = new SemaphoreSlim(1, 1);
|
||||||
|
public readonly ManualResetEventSlim OnSentData = new ManualResetEventSlim(false);
|
||||||
|
public readonly ManualResetEventSlim OnReceivedData = new ManualResetEventSlim(false);
|
||||||
|
public SocketAsyncEventArgs SendEventArgs { get; set; } = new SocketAsyncEventArgs();
|
||||||
|
public SocketAsyncEventArgs ReceiveEventArgs { get; set; } = new SocketAsyncEventArgs();
|
||||||
|
public DateTime LastQuery { get; set; } = DateTime.Now;
|
||||||
|
}
|
||||||
|
}
|
@ -1,58 +1,41 @@
|
|||||||
using SharedLibraryCore.Exceptions;
|
using SharedLibraryCore;
|
||||||
|
using SharedLibraryCore.Exceptions;
|
||||||
using SharedLibraryCore.Interfaces;
|
using SharedLibraryCore.Interfaces;
|
||||||
|
using SharedLibraryCore.RCon;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace SharedLibraryCore.RCon
|
namespace IW4MAdmin.Application.RCon
|
||||||
{
|
{
|
||||||
class ConnectionState
|
/// <summary>
|
||||||
{
|
/// implementation of IRConConnection
|
||||||
~ConnectionState()
|
/// </summary>
|
||||||
{
|
public class RConConnection : IRConConnection
|
||||||
OnComplete.Dispose();
|
|
||||||
OnSentData.Dispose();
|
|
||||||
OnReceivedData.Dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int ConnectionAttempts { get; set; }
|
|
||||||
const int BufferSize = 4096;
|
|
||||||
public readonly byte[] ReceiveBuffer = new byte[BufferSize];
|
|
||||||
public readonly SemaphoreSlim OnComplete = new SemaphoreSlim(1, 1);
|
|
||||||
public readonly ManualResetEventSlim OnSentData = new ManualResetEventSlim(false);
|
|
||||||
public readonly ManualResetEventSlim OnReceivedData = new ManualResetEventSlim(false);
|
|
||||||
public SocketAsyncEventArgs SendEventArgs { get; set; } = new SocketAsyncEventArgs();
|
|
||||||
public SocketAsyncEventArgs ReceiveEventArgs { get; set; } = new SocketAsyncEventArgs();
|
|
||||||
public DateTime LastQuery { get; set; } = DateTime.Now;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class Connection
|
|
||||||
{
|
{
|
||||||
static readonly ConcurrentDictionary<EndPoint, ConnectionState> ActiveQueries = new ConcurrentDictionary<EndPoint, ConnectionState>();
|
static readonly ConcurrentDictionary<EndPoint, ConnectionState> ActiveQueries = new ConcurrentDictionary<EndPoint, ConnectionState>();
|
||||||
public IPEndPoint Endpoint { get; private set; }
|
public IPEndPoint Endpoint { get; private set; }
|
||||||
public string RConPassword { get; private set; }
|
public string RConPassword { get; private set; }
|
||||||
|
|
||||||
private readonly ILogger Log;
|
private IRConParserConfiguration config;
|
||||||
private IRConParserConfiguration Config;
|
private readonly ILogger _log;
|
||||||
private readonly Encoding defaultEncoding;
|
private readonly Encoding _gameEncoding;
|
||||||
|
|
||||||
public Connection(string ipAddress, int port, string password, ILogger log, IRConParserConfiguration config)
|
public RConConnection(string ipAddress, int port, string password, ILogger log, Encoding gameEncoding)
|
||||||
{
|
{
|
||||||
Endpoint = new IPEndPoint(IPAddress.Parse(ipAddress), port);
|
Endpoint = new IPEndPoint(IPAddress.Parse(ipAddress), port);
|
||||||
defaultEncoding = Encoding.GetEncoding("windows-1252");
|
_gameEncoding = gameEncoding;
|
||||||
RConPassword = password;
|
RConPassword = password;
|
||||||
Log = log;
|
_log = log;
|
||||||
Config = config;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetConfiguration(IRConParserConfiguration config)
|
public void SetConfiguration(IRConParserConfiguration config)
|
||||||
{
|
{
|
||||||
Config = config;
|
this.config = config;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<string[]> SendQueryAsync(StaticHelpers.QueryType type, string parameters = "")
|
public async Task<string[]> SendQueryAsync(StaticHelpers.QueryType type, string parameters = "")
|
||||||
@ -65,7 +48,7 @@ namespace SharedLibraryCore.RCon
|
|||||||
var connectionState = ActiveQueries[this.Endpoint];
|
var connectionState = ActiveQueries[this.Endpoint];
|
||||||
|
|
||||||
#if DEBUG == true
|
#if DEBUG == true
|
||||||
Log.WriteDebug($"Waiting for semaphore to be released [{this.Endpoint}]");
|
_log.WriteDebug($"Waiting for semaphore to be released [{this.Endpoint}]");
|
||||||
#endif
|
#endif
|
||||||
// enter the semaphore so only one query is sent at a time per server.
|
// enter the semaphore so only one query is sent at a time per server.
|
||||||
await connectionState.OnComplete.WaitAsync();
|
await connectionState.OnComplete.WaitAsync();
|
||||||
@ -80,17 +63,17 @@ namespace SharedLibraryCore.RCon
|
|||||||
connectionState.LastQuery = DateTime.Now;
|
connectionState.LastQuery = DateTime.Now;
|
||||||
|
|
||||||
#if DEBUG == true
|
#if DEBUG == true
|
||||||
Log.WriteDebug($"Semaphore has been released [{this.Endpoint}]");
|
_log.WriteDebug($"Semaphore has been released [{this.Endpoint}]");
|
||||||
Log.WriteDebug($"Query [{this.Endpoint},{type.ToString()},{parameters}]");
|
_log.WriteDebug($"Query [{this.Endpoint},{type.ToString()},{parameters}]");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
byte[] payload = null;
|
byte[] payload = null;
|
||||||
bool waitForResponse = Config.WaitForResponse;
|
bool waitForResponse = config.WaitForResponse;
|
||||||
|
|
||||||
string convertEncoding(string text)
|
string convertEncoding(string text)
|
||||||
{
|
{
|
||||||
byte[] convertedBytes = Utilities.EncodingType.GetBytes(text);
|
byte[] convertedBytes = Utilities.EncodingType.GetBytes(text);
|
||||||
return defaultEncoding.GetString(convertedBytes);
|
return _gameEncoding.GetString(convertedBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
@ -102,25 +85,25 @@ namespace SharedLibraryCore.RCon
|
|||||||
{
|
{
|
||||||
case StaticHelpers.QueryType.GET_DVAR:
|
case StaticHelpers.QueryType.GET_DVAR:
|
||||||
waitForResponse |= true;
|
waitForResponse |= true;
|
||||||
payload = string.Format(Config.CommandPrefixes.RConGetDvar, convertedRConPassword, convertedParameters + '\0').Select(Convert.ToByte).ToArray();
|
payload = string.Format(config.CommandPrefixes.RConGetDvar, convertedRConPassword, convertedParameters + '\0').Select(Convert.ToByte).ToArray();
|
||||||
break;
|
break;
|
||||||
case StaticHelpers.QueryType.SET_DVAR:
|
case StaticHelpers.QueryType.SET_DVAR:
|
||||||
payload = string.Format(Config.CommandPrefixes.RConSetDvar, convertedRConPassword, convertedParameters + '\0').Select(Convert.ToByte).ToArray();
|
payload = string.Format(config.CommandPrefixes.RConSetDvar, convertedRConPassword, convertedParameters + '\0').Select(Convert.ToByte).ToArray();
|
||||||
break;
|
break;
|
||||||
case StaticHelpers.QueryType.COMMAND:
|
case StaticHelpers.QueryType.COMMAND:
|
||||||
payload = string.Format(Config.CommandPrefixes.RConCommand, convertedRConPassword, convertedParameters + '\0').Select(Convert.ToByte).ToArray();
|
payload = string.Format(config.CommandPrefixes.RConCommand, convertedRConPassword, convertedParameters + '\0').Select(Convert.ToByte).ToArray();
|
||||||
break;
|
break;
|
||||||
case StaticHelpers.QueryType.GET_STATUS:
|
case StaticHelpers.QueryType.GET_STATUS:
|
||||||
waitForResponse |= true;
|
waitForResponse |= true;
|
||||||
payload = (Config.CommandPrefixes.RConGetStatus + '\0').Select(Convert.ToByte).ToArray();
|
payload = (config.CommandPrefixes.RConGetStatus + '\0').Select(Convert.ToByte).ToArray();
|
||||||
break;
|
break;
|
||||||
case StaticHelpers.QueryType.GET_INFO:
|
case StaticHelpers.QueryType.GET_INFO:
|
||||||
waitForResponse |= true;
|
waitForResponse |= true;
|
||||||
payload = (Config.CommandPrefixes.RConGetInfo + '\0').Select(Convert.ToByte).ToArray();
|
payload = (config.CommandPrefixes.RConGetInfo + '\0').Select(Convert.ToByte).ToArray();
|
||||||
break;
|
break;
|
||||||
case StaticHelpers.QueryType.COMMAND_STATUS:
|
case StaticHelpers.QueryType.COMMAND_STATUS:
|
||||||
waitForResponse |= true;
|
waitForResponse |= true;
|
||||||
payload = string.Format(Config.CommandPrefixes.RConCommand, convertedRConPassword, "status\0").Select(Convert.ToByte).ToArray();
|
payload = string.Format(config.CommandPrefixes.RConCommand, convertedRConPassword, "status\0").Select(Convert.ToByte).ToArray();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -148,7 +131,7 @@ namespace SharedLibraryCore.RCon
|
|||||||
connectionState.OnReceivedData.Reset();
|
connectionState.OnReceivedData.Reset();
|
||||||
connectionState.ConnectionAttempts++;
|
connectionState.ConnectionAttempts++;
|
||||||
#if DEBUG == true
|
#if DEBUG == true
|
||||||
Log.WriteDebug($"Sending {payload.Length} bytes to [{this.Endpoint}] ({connectionState.ConnectionAttempts}/{StaticHelpers.AllowedConnectionFails})");
|
_log.WriteDebug($"Sending {payload.Length} bytes to [{this.Endpoint}] ({connectionState.ConnectionAttempts}/{StaticHelpers.AllowedConnectionFails})");
|
||||||
#endif
|
#endif
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -182,7 +165,7 @@ namespace SharedLibraryCore.RCon
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
string responseString = defaultEncoding.GetString(response, 0, response.Length) + '\n';
|
string responseString = _gameEncoding.GetString(response, 0, response.Length) + '\n';
|
||||||
|
|
||||||
// note: not all games respond if the pasword is wrong or not set
|
// note: not all games respond if the pasword is wrong or not set
|
||||||
if (responseString.Contains("Invalid password") || responseString.Contains("rconpassword"))
|
if (responseString.Contains("Invalid password") || responseString.Contains("rconpassword"))
|
||||||
@ -195,7 +178,7 @@ namespace SharedLibraryCore.RCon
|
|||||||
throw new NetworkException(Utilities.CurrentLocalization.LocalizationIndex["SERVER_ERROR_RCON_NOTSET"]);
|
throw new NetworkException(Utilities.CurrentLocalization.LocalizationIndex["SERVER_ERROR_RCON_NOTSET"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (responseString.Contains(Config.ServerNotRunningResponse))
|
if (responseString.Contains(config.ServerNotRunningResponse))
|
||||||
{
|
{
|
||||||
throw new ServerException(Utilities.CurrentLocalization.LocalizationIndex["SERVER_ERROR_NOT_RUNNING"].FormatExt(Endpoint.ToString()));
|
throw new ServerException(Utilities.CurrentLocalization.LocalizationIndex["SERVER_ERROR_NOT_RUNNING"].FormatExt(Endpoint.ToString()));
|
||||||
}
|
}
|
||||||
@ -269,7 +252,7 @@ namespace SharedLibraryCore.RCon
|
|||||||
private void OnDataReceived(object sender, SocketAsyncEventArgs e)
|
private void OnDataReceived(object sender, SocketAsyncEventArgs e)
|
||||||
{
|
{
|
||||||
#if DEBUG == true
|
#if DEBUG == true
|
||||||
Log.WriteDebug($"Read {e.BytesTransferred} bytes from {e.RemoteEndPoint.ToString()}");
|
_log.WriteDebug($"Read {e.BytesTransferred} bytes from {e.RemoteEndPoint.ToString()}");
|
||||||
#endif
|
#endif
|
||||||
ActiveQueries[this.Endpoint].OnReceivedData.Set();
|
ActiveQueries[this.Endpoint].OnReceivedData.Set();
|
||||||
}
|
}
|
||||||
@ -277,7 +260,7 @@ namespace SharedLibraryCore.RCon
|
|||||||
private void OnDataSent(object sender, SocketAsyncEventArgs e)
|
private void OnDataSent(object sender, SocketAsyncEventArgs e)
|
||||||
{
|
{
|
||||||
#if DEBUG == true
|
#if DEBUG == true
|
||||||
Log.WriteDebug($"Sent {e.Buffer?.Length} bytes to {e.ConnectSocket?.RemoteEndPoint?.ToString()}");
|
_log.WriteDebug($"Sent {e.Buffer?.Length} bytes to {e.ConnectSocket?.RemoteEndPoint?.ToString()}");
|
||||||
#endif
|
#endif
|
||||||
ActiveQueries[this.Endpoint].OnSentData.Set();
|
ActiveQueries[this.Endpoint].OnSentData.Set();
|
||||||
}
|
}
|
@ -65,13 +65,13 @@ namespace IW4MAdmin.Application.RconParsers
|
|||||||
public bool CanGenerateLogPath { get; set; } = true;
|
public bool CanGenerateLogPath { get; set; } = true;
|
||||||
public string Name { get; set; } = "Call of Duty";
|
public string Name { get; set; } = "Call of Duty";
|
||||||
|
|
||||||
public async Task<string[]> ExecuteCommandAsync(Connection connection, string command)
|
public async Task<string[]> ExecuteCommandAsync(IRConConnection connection, string command)
|
||||||
{
|
{
|
||||||
var response = await connection.SendQueryAsync(StaticHelpers.QueryType.COMMAND, command);
|
var response = await connection.SendQueryAsync(StaticHelpers.QueryType.COMMAND, command);
|
||||||
return response.Skip(1).ToArray();
|
return response.Skip(1).ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<Dvar<T>> GetDvarAsync<T>(Connection connection, string dvarName)
|
public async Task<Dvar<T>> GetDvarAsync<T>(IRConConnection connection, string dvarName)
|
||||||
{
|
{
|
||||||
string[] lineSplit = await connection.SendQueryAsync(StaticHelpers.QueryType.GET_DVAR, dvarName);
|
string[] lineSplit = await connection.SendQueryAsync(StaticHelpers.QueryType.GET_DVAR, dvarName);
|
||||||
string response = string.Join('\n', lineSplit.Skip(1));
|
string response = string.Join('\n', lineSplit.Skip(1));
|
||||||
@ -105,7 +105,7 @@ namespace IW4MAdmin.Application.RconParsers
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual async Task<(List<EFClient>, string)> GetStatusAsync(Connection connection)
|
public virtual async Task<(List<EFClient>, string)> GetStatusAsync(IRConConnection connection)
|
||||||
{
|
{
|
||||||
string[] response = await connection.SendQueryAsync(StaticHelpers.QueryType.COMMAND_STATUS);
|
string[] response = await connection.SendQueryAsync(StaticHelpers.QueryType.COMMAND_STATUS);
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
@ -132,7 +132,7 @@ namespace IW4MAdmin.Application.RconParsers
|
|||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<bool> SetDvarAsync(Connection connection, string dvarName, object dvarValue)
|
public async Task<bool> SetDvarAsync(IRConConnection connection, string dvarName, object dvarValue)
|
||||||
{
|
{
|
||||||
return (await connection.SendQueryAsync(StaticHelpers.QueryType.SET_DVAR, $"{dvarName} {dvarValue}")).Length > 0;
|
return (await connection.SendQueryAsync(StaticHelpers.QueryType.SET_DVAR, $"{dvarName} {dvarValue}")).Length > 0;
|
||||||
}
|
}
|
||||||
|
@ -6,8 +6,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Plugins", "Plugins", "{26E8
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{8C8F3945-0AEF-4949-A1F7-B18E952E50BC}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{8C8F3945-0AEF-4949-A1F7-B18E952E50BC}"
|
||||||
ProjectSection(SolutionItems) = preProject
|
ProjectSection(SolutionItems) = preProject
|
||||||
GameFiles\IW4x\userraw\_commands.gsc = GameFiles\IW4x\userraw\_commands.gsc
|
GameFiles\IW4x\userraw\scripts\_commands.gsc = GameFiles\IW4x\userraw\scripts\_commands.gsc
|
||||||
GameFiles\IW4x\userraw\_customcallbacks.gsc = GameFiles\IW4x\userraw\_customcallbacks.gsc
|
GameFiles\IW4x\userraw\scripts\_customcallbacks.gsc = GameFiles\IW4x\userraw\scripts\_customcallbacks.gsc
|
||||||
azure-pipelines.yml = azure-pipelines.yml
|
azure-pipelines.yml = azure-pipelines.yml
|
||||||
PostPublish.ps1 = PostPublish.ps1
|
PostPublish.ps1 = PostPublish.ps1
|
||||||
README.md = README.md
|
README.md = README.md
|
||||||
@ -57,6 +57,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AutomessageFeed", "Plugins\
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LiveRadar", "Plugins\LiveRadar\LiveRadar.csproj", "{00A1FED2-2254-4AF7-A5DB-2357FA7C88CD}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LiveRadar", "Plugins\LiveRadar\LiveRadar.csproj", "{00A1FED2-2254-4AF7-A5DB-2357FA7C88CD}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{3065279E-17F0-4CE0-AF5B-014E04263D77}"
|
||||||
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ApplicationTests", "Tests\ApplicationTests\ApplicationTests.csproj", "{581FA7AF-FEF6-483C-A7D0-2D13EF50801B}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
@ -405,6 +409,29 @@ Global
|
|||||||
{00A1FED2-2254-4AF7-A5DB-2357FA7C88CD}.Release|x64.Build.0 = Release|Any CPU
|
{00A1FED2-2254-4AF7-A5DB-2357FA7C88CD}.Release|x64.Build.0 = Release|Any CPU
|
||||||
{00A1FED2-2254-4AF7-A5DB-2357FA7C88CD}.Release|x86.ActiveCfg = Release|Any CPU
|
{00A1FED2-2254-4AF7-A5DB-2357FA7C88CD}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
{00A1FED2-2254-4AF7-A5DB-2357FA7C88CD}.Release|x86.Build.0 = Release|Any CPU
|
{00A1FED2-2254-4AF7-A5DB-2357FA7C88CD}.Release|x86.Build.0 = Release|Any CPU
|
||||||
|
{581FA7AF-FEF6-483C-A7D0-2D13EF50801B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{581FA7AF-FEF6-483C-A7D0-2D13EF50801B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{581FA7AF-FEF6-483C-A7D0-2D13EF50801B}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||||
|
{581FA7AF-FEF6-483C-A7D0-2D13EF50801B}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||||
|
{581FA7AF-FEF6-483C-A7D0-2D13EF50801B}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{581FA7AF-FEF6-483C-A7D0-2D13EF50801B}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{581FA7AF-FEF6-483C-A7D0-2D13EF50801B}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{581FA7AF-FEF6-483C-A7D0-2D13EF50801B}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
|
{581FA7AF-FEF6-483C-A7D0-2D13EF50801B}.Prerelease|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{581FA7AF-FEF6-483C-A7D0-2D13EF50801B}.Prerelease|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||||
|
{581FA7AF-FEF6-483C-A7D0-2D13EF50801B}.Prerelease|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||||
|
{581FA7AF-FEF6-483C-A7D0-2D13EF50801B}.Prerelease|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{581FA7AF-FEF6-483C-A7D0-2D13EF50801B}.Prerelease|x64.Build.0 = Debug|Any CPU
|
||||||
|
{581FA7AF-FEF6-483C-A7D0-2D13EF50801B}.Prerelease|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{581FA7AF-FEF6-483C-A7D0-2D13EF50801B}.Prerelease|x86.Build.0 = Debug|Any CPU
|
||||||
|
{581FA7AF-FEF6-483C-A7D0-2D13EF50801B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{581FA7AF-FEF6-483C-A7D0-2D13EF50801B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{581FA7AF-FEF6-483C-A7D0-2D13EF50801B}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||||
|
{581FA7AF-FEF6-483C-A7D0-2D13EF50801B}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||||
|
{581FA7AF-FEF6-483C-A7D0-2D13EF50801B}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{581FA7AF-FEF6-483C-A7D0-2D13EF50801B}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{581FA7AF-FEF6-483C-A7D0-2D13EF50801B}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{581FA7AF-FEF6-483C-A7D0-2D13EF50801B}.Release|x86.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
@ -421,6 +448,7 @@ Global
|
|||||||
{776B348B-F818-4A0F-A625-D0AF8BAD3E9B} = {A848FCF1-8527-4AA8-A1AA-50D29695C678}
|
{776B348B-F818-4A0F-A625-D0AF8BAD3E9B} = {A848FCF1-8527-4AA8-A1AA-50D29695C678}
|
||||||
{F5815359-CFC7-44B4-9A3B-C04BACAD5836} = {26E8B310-269E-46D4-A612-24601F16065F}
|
{F5815359-CFC7-44B4-9A3B-C04BACAD5836} = {26E8B310-269E-46D4-A612-24601F16065F}
|
||||||
{00A1FED2-2254-4AF7-A5DB-2357FA7C88CD} = {26E8B310-269E-46D4-A612-24601F16065F}
|
{00A1FED2-2254-4AF7-A5DB-2357FA7C88CD} = {26E8B310-269E-46D4-A612-24601F16065F}
|
||||||
|
{581FA7AF-FEF6-483C-A7D0-2D13EF50801B} = {3065279E-17F0-4CE0-AF5B-014E04263D77}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
SolutionGuid = {84F8F8E0-1F73-41E0-BD8D-BB6676E2EE87}
|
SolutionGuid = {84F8F8E0-1F73-41E0-BD8D-BB6676E2EE87}
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.SyndicationFeed.ReaderWriter" Version="1.0.2" />
|
<PackageReference Include="Microsoft.SyndicationFeed.ReaderWriter" Version="1.0.2" />
|
||||||
<PackageReference Include="RaidMax.IW4MAdmin.SharedLibraryCore" Version="2.2.6" PrivateAssets="All" />
|
<PackageReference Include="RaidMax.IW4MAdmin.SharedLibraryCore" Version="2.2.7" PrivateAssets="All" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
|
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
|
||||||
|
@ -20,14 +20,19 @@ namespace AutomessageFeed
|
|||||||
|
|
||||||
public string Author => "RaidMax";
|
public string Author => "RaidMax";
|
||||||
|
|
||||||
private Configuration _configuration;
|
|
||||||
private int _currentFeedItem;
|
private int _currentFeedItem;
|
||||||
|
private readonly IConfigurationHandler<Configuration> _configurationHandler;
|
||||||
|
|
||||||
|
public Plugin(IConfigurationHandlerFactory configurationHandlerFactory)
|
||||||
|
{
|
||||||
|
_configurationHandler = configurationHandlerFactory.GetConfigurationHandler<Configuration>("AutomessageFeedPluginSettings");
|
||||||
|
}
|
||||||
|
|
||||||
private async Task<string> GetNextFeedItem(Server server)
|
private async Task<string> GetNextFeedItem(Server server)
|
||||||
{
|
{
|
||||||
var items = new List<string>();
|
var items = new List<string>();
|
||||||
|
|
||||||
using (var reader = XmlReader.Create(_configuration.FeedUrl, new XmlReaderSettings() { Async = true }))
|
using (var reader = XmlReader.Create(_configurationHandler.Configuration().FeedUrl, new XmlReaderSettings() { Async = true }))
|
||||||
{
|
{
|
||||||
var feedReader = new RssFeedReader(reader);
|
var feedReader = new RssFeedReader(reader);
|
||||||
|
|
||||||
@ -43,7 +48,7 @@ namespace AutomessageFeed
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_currentFeedItem < items.Count && (_configuration.MaxFeedItems == 0 || _currentFeedItem < _configuration.MaxFeedItems))
|
if (_currentFeedItem < items.Count && (_configurationHandler.Configuration().MaxFeedItems == 0 || _currentFeedItem < _configurationHandler.Configuration().MaxFeedItems))
|
||||||
{
|
{
|
||||||
_currentFeedItem++;
|
_currentFeedItem++;
|
||||||
return items[_currentFeedItem - 1];
|
return items[_currentFeedItem - 1];
|
||||||
@ -60,15 +65,12 @@ namespace AutomessageFeed
|
|||||||
|
|
||||||
public async Task OnLoadAsync(IManager manager)
|
public async Task OnLoadAsync(IManager manager)
|
||||||
{
|
{
|
||||||
var cfg = new BaseConfigurationHandler<Configuration>("AutomessageFeedPluginSettings");
|
if (_configurationHandler.Configuration() == null)
|
||||||
if (cfg.Configuration() == null)
|
|
||||||
{
|
{
|
||||||
cfg.Set((Configuration)new Configuration().Generate());
|
_configurationHandler.Set((Configuration)new Configuration().Generate());
|
||||||
await cfg.Save();
|
await _configurationHandler.Save();
|
||||||
}
|
}
|
||||||
|
|
||||||
_configuration = cfg.Configuration();
|
|
||||||
|
|
||||||
manager.GetMessageTokens().Add(new MessageToken("FEED", GetNextFeedItem));
|
manager.GetMessageTokens().Add(new MessageToken("FEED", GetNextFeedItem));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="RaidMax.IW4MAdmin.SharedLibraryCore" Version="2.2.6" PrivateAssets="All" />
|
<PackageReference Include="RaidMax.IW4MAdmin.SharedLibraryCore" Version="2.2.7" PrivateAssets="All" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
|
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using Microsoft.AspNetCore.Mvc;
|
using LiveRadar.Configuration;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using SharedLibraryCore;
|
using SharedLibraryCore;
|
||||||
using SharedLibraryCore.Dtos;
|
using SharedLibraryCore.Dtos;
|
||||||
@ -16,10 +17,12 @@ namespace LiveRadar.Web.Controllers
|
|||||||
};
|
};
|
||||||
|
|
||||||
private readonly IManager _manager;
|
private readonly IManager _manager;
|
||||||
|
private readonly LiveRadarConfiguration _config;
|
||||||
|
|
||||||
public RadarController(IManager manager) : base(manager)
|
public RadarController(IManager manager, IConfigurationHandlerFactory configurationHandlerFactory) : base(manager)
|
||||||
{
|
{
|
||||||
_manager = manager;
|
_manager = manager;
|
||||||
|
_config = configurationHandlerFactory.GetConfigurationHandler<LiveRadarConfiguration>("LiveRadarConfiguration").Configuration() ?? new LiveRadarConfiguration();
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
@ -45,7 +48,7 @@ namespace LiveRadar.Web.Controllers
|
|||||||
public IActionResult Map(long? serverId = null)
|
public IActionResult Map(long? serverId = null)
|
||||||
{
|
{
|
||||||
var server = serverId == null ? _manager.GetServers().FirstOrDefault() : _manager.GetServers().FirstOrDefault(_server => _server.EndPoint == serverId);
|
var server = serverId == null ? _manager.GetServers().FirstOrDefault() : _manager.GetServers().FirstOrDefault(_server => _server.EndPoint == serverId);
|
||||||
var map = Plugin.Config.Configuration().Maps.FirstOrDefault(_map => _map.Name == server.CurrentMap.Name);
|
var map = _config.Maps.FirstOrDefault(_map => _map.Name == server.CurrentMap.Name);
|
||||||
|
|
||||||
if (map != null)
|
if (map != null)
|
||||||
{
|
{
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="RaidMax.IW4MAdmin.SharedLibraryCore" Version="2.2.6" PrivateAssets="All" />
|
<PackageReference Include="RaidMax.IW4MAdmin.SharedLibraryCore" Version="2.2.7" PrivateAssets="All" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -16,7 +16,12 @@ namespace LiveRadar
|
|||||||
|
|
||||||
public string Author => "RaidMax";
|
public string Author => "RaidMax";
|
||||||
|
|
||||||
internal static BaseConfigurationHandler<LiveRadarConfiguration> Config;
|
private readonly IConfigurationHandler<LiveRadarConfiguration> _configurationHandler;
|
||||||
|
|
||||||
|
public Plugin(IConfigurationHandlerFactory configurationHandlerFactory)
|
||||||
|
{
|
||||||
|
_configurationHandler = configurationHandlerFactory.GetConfigurationHandler<LiveRadarConfiguration>("LiveRadarConfiguration");
|
||||||
|
}
|
||||||
|
|
||||||
public Task OnEventAsync(GameEvent E, Server S)
|
public Task OnEventAsync(GameEvent E, Server S)
|
||||||
{
|
{
|
||||||
@ -36,7 +41,7 @@ namespace LiveRadar
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
catch(Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
S.Logger.WriteWarning($"Could not parse live radar output: {e.Data}");
|
S.Logger.WriteWarning($"Could not parse live radar output: {e.Data}");
|
||||||
S.Logger.WriteDebug(e.GetExceptionInfo());
|
S.Logger.WriteDebug(e.GetExceptionInfo());
|
||||||
@ -49,12 +54,10 @@ namespace LiveRadar
|
|||||||
|
|
||||||
public async Task OnLoadAsync(IManager manager)
|
public async Task OnLoadAsync(IManager manager)
|
||||||
{
|
{
|
||||||
// load custom configuration
|
if (_configurationHandler.Configuration() == null)
|
||||||
Config = new BaseConfigurationHandler<LiveRadarConfiguration>("LiveRadarConfiguration");
|
|
||||||
if (Config.Configuration() == null)
|
|
||||||
{
|
{
|
||||||
Config.Set((LiveRadarConfiguration)new LiveRadarConfiguration().Generate());
|
_configurationHandler.Set((LiveRadarConfiguration)new LiveRadarConfiguration().Generate());
|
||||||
await Config.Save();
|
await _configurationHandler.Save();
|
||||||
}
|
}
|
||||||
|
|
||||||
manager.GetPageList().Pages.Add(Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_RADAR_TITLE"], "/Radar/All");
|
manager.GetPageList().Pages.Add(Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_RADAR_TITLE"], "/Radar/All");
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
</Target>
|
</Target>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="RaidMax.IW4MAdmin.SharedLibraryCore" Version="2.2.6" PrivateAssets="All" />
|
<PackageReference Include="RaidMax.IW4MAdmin.SharedLibraryCore" Version="2.2.7" PrivateAssets="All" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -4,7 +4,6 @@ using System.Threading.Tasks;
|
|||||||
using IW4MAdmin.Plugins.Login.Commands;
|
using IW4MAdmin.Plugins.Login.Commands;
|
||||||
using SharedLibraryCore;
|
using SharedLibraryCore;
|
||||||
using SharedLibraryCore.Commands;
|
using SharedLibraryCore.Commands;
|
||||||
using SharedLibraryCore.Configuration;
|
|
||||||
using SharedLibraryCore.Database.Models;
|
using SharedLibraryCore.Database.Models;
|
||||||
using SharedLibraryCore.Exceptions;
|
using SharedLibraryCore.Exceptions;
|
||||||
using SharedLibraryCore.Interfaces;
|
using SharedLibraryCore.Interfaces;
|
||||||
@ -20,11 +19,16 @@ namespace IW4MAdmin.Plugins.Login
|
|||||||
public string Author => "RaidMax";
|
public string Author => "RaidMax";
|
||||||
|
|
||||||
public static ConcurrentDictionary<int, bool> AuthorizedClients { get; private set; }
|
public static ConcurrentDictionary<int, bool> AuthorizedClients { get; private set; }
|
||||||
private Configuration Config;
|
private readonly IConfigurationHandler<Configuration> _configHandler;
|
||||||
|
|
||||||
|
public Plugin(IConfigurationHandlerFactory configurationHandlerFactory)
|
||||||
|
{
|
||||||
|
_configHandler = configurationHandlerFactory.GetConfigurationHandler<Configuration>("LoginPluginSettings");
|
||||||
|
}
|
||||||
|
|
||||||
public Task OnEventAsync(GameEvent E, Server S)
|
public Task OnEventAsync(GameEvent E, Server S)
|
||||||
{
|
{
|
||||||
if (E.IsRemote || Config.RequirePrivilegedClientLogin == false)
|
if (E.IsRemote || _configHandler.Configuration().RequirePrivilegedClientLogin == false)
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
|
|
||||||
if (E.Type == GameEvent.EventType.Connect)
|
if (E.Type == GameEvent.EventType.Connect)
|
||||||
@ -72,14 +76,11 @@ namespace IW4MAdmin.Plugins.Login
|
|||||||
{
|
{
|
||||||
AuthorizedClients = new ConcurrentDictionary<int, bool>();
|
AuthorizedClients = new ConcurrentDictionary<int, bool>();
|
||||||
|
|
||||||
var cfg = new BaseConfigurationHandler<Configuration>("LoginPluginSettings");
|
if (_configHandler.Configuration() == null)
|
||||||
if (cfg.Configuration() == null)
|
|
||||||
{
|
{
|
||||||
cfg.Set((Configuration)new Configuration().Generate());
|
_configHandler.Set((Configuration)new Configuration().Generate());
|
||||||
await cfg.Save();
|
await _configHandler.Save();
|
||||||
}
|
}
|
||||||
|
|
||||||
Config = cfg.Configuration();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task OnTickAsync(Server S) => Task.CompletedTask;
|
public Task OnTickAsync(Server S) => Task.CompletedTask;
|
||||||
|
@ -17,18 +17,23 @@ namespace IW4MAdmin.Plugins.ProfanityDeterment
|
|||||||
|
|
||||||
public string Author => "RaidMax";
|
public string Author => "RaidMax";
|
||||||
|
|
||||||
BaseConfigurationHandler<Configuration> Settings;
|
private readonly IConfigurationHandler<Configuration> _configHandler;
|
||||||
|
|
||||||
|
public Plugin(IConfigurationHandlerFactory configurationHandlerFactory)
|
||||||
|
{
|
||||||
|
_configHandler = configurationHandlerFactory.GetConfigurationHandler<Configuration>("ProfanityDetermentSettings");
|
||||||
|
}
|
||||||
|
|
||||||
public Task OnEventAsync(GameEvent E, Server S)
|
public Task OnEventAsync(GameEvent E, Server S)
|
||||||
{
|
{
|
||||||
if (!Settings.Configuration().EnableProfanityDeterment)
|
if (!_configHandler.Configuration().EnableProfanityDeterment)
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
|
|
||||||
if (E.Type == GameEvent.EventType.Connect)
|
if (E.Type == GameEvent.EventType.Connect)
|
||||||
{
|
{
|
||||||
E.Origin.SetAdditionalProperty("_profanityInfringements", 0);
|
E.Origin.SetAdditionalProperty("_profanityInfringements", 0);
|
||||||
|
|
||||||
var objectionalWords = Settings.Configuration().OffensiveWords;
|
var objectionalWords = _configHandler.Configuration().OffensiveWords;
|
||||||
var matchedFilters = new List<string>();
|
var matchedFilters = new List<string>();
|
||||||
bool containsObjectionalWord = false;
|
bool containsObjectionalWord = false;
|
||||||
|
|
||||||
@ -51,7 +56,7 @@ namespace IW4MAdmin.Plugins.ProfanityDeterment
|
|||||||
AutomatedOffense = $"{E.Origin.Name} - {string.Join(",", matchedFilters)}"
|
AutomatedOffense = $"{E.Origin.Name} - {string.Join(",", matchedFilters)}"
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
E.Origin.Kick(Settings.Configuration().ProfanityKickMessage, sender);
|
E.Origin.Kick(_configHandler.Configuration().ProfanityKickMessage, sender);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,7 +67,7 @@ namespace IW4MAdmin.Plugins.ProfanityDeterment
|
|||||||
|
|
||||||
if (E.Type == GameEvent.EventType.Say)
|
if (E.Type == GameEvent.EventType.Say)
|
||||||
{
|
{
|
||||||
var objectionalWords = Settings.Configuration().OffensiveWords;
|
var objectionalWords = _configHandler.Configuration().OffensiveWords;
|
||||||
bool containsObjectionalWord = false;
|
bool containsObjectionalWord = false;
|
||||||
var matchedFilters = new List<string>();
|
var matchedFilters = new List<string>();
|
||||||
|
|
||||||
@ -88,15 +93,15 @@ namespace IW4MAdmin.Plugins.ProfanityDeterment
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (profanityInfringments >= Settings.Configuration().KickAfterInfringementCount)
|
if (profanityInfringments >= _configHandler.Configuration().KickAfterInfringementCount)
|
||||||
{
|
{
|
||||||
E.Origin.Kick(Settings.Configuration().ProfanityKickMessage, sender);
|
E.Origin.Kick(_configHandler.Configuration().ProfanityKickMessage, sender);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (profanityInfringments < Settings.Configuration().KickAfterInfringementCount)
|
else if (profanityInfringments < _configHandler.Configuration().KickAfterInfringementCount)
|
||||||
{
|
{
|
||||||
E.Origin.SetAdditionalProperty("_profanityInfringements", profanityInfringments + 1);
|
E.Origin.SetAdditionalProperty("_profanityInfringements", profanityInfringments + 1);
|
||||||
E.Origin.Warn(Settings.Configuration().ProfanityWarningMessage, sender);
|
E.Origin.Warn(_configHandler.Configuration().ProfanityWarningMessage, sender);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -105,12 +110,10 @@ namespace IW4MAdmin.Plugins.ProfanityDeterment
|
|||||||
|
|
||||||
public async Task OnLoadAsync(IManager manager)
|
public async Task OnLoadAsync(IManager manager)
|
||||||
{
|
{
|
||||||
// load custom configuration
|
if (_configHandler.Configuration() == null)
|
||||||
Settings = new BaseConfigurationHandler<Configuration>("ProfanityDetermentSettings");
|
|
||||||
if (Settings.Configuration() == null)
|
|
||||||
{
|
{
|
||||||
Settings.Set((Configuration)new Configuration().Generate());
|
_configHandler.Set((Configuration)new Configuration().Generate());
|
||||||
await Settings.Save();
|
await _configHandler.Save();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="RaidMax.IW4MAdmin.SharedLibraryCore" Version="2.2.6" PrivateAssets="All" />
|
<PackageReference Include="RaidMax.IW4MAdmin.SharedLibraryCore" Version="2.2.7" PrivateAssets="All" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
|
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
|
||||||
|
@ -17,7 +17,7 @@ namespace IW4MAdmin.Plugins.Stats.Config
|
|||||||
public IDictionary<DetectionType, DistributionConfiguration> DetectionDistributions { get; set; }
|
public IDictionary<DetectionType, DistributionConfiguration> DetectionDistributions { get; set; }
|
||||||
public IDictionary<long, DetectionType[]> ServerDetectionTypes { get; set; }
|
public IDictionary<long, DetectionType[]> ServerDetectionTypes { get; set; }
|
||||||
|
|
||||||
public string Name() => "Stats";
|
public string Name() => "StatsPluginSettings";
|
||||||
public IBaseConfiguration Generate()
|
public IBaseConfiguration Generate()
|
||||||
{
|
{
|
||||||
EnableAntiCheat = Utilities.PromptBool(Utilities.CurrentLocalization.LocalizationIndex["PLUGIN_STATS_SETUP_ENABLEAC"]);
|
EnableAntiCheat = Utilities.PromptBool(Utilities.CurrentLocalization.LocalizationIndex["PLUGIN_STATS_SETUP_ENABLEAC"]);
|
||||||
|
@ -21,8 +21,8 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
|||||||
var killstreakMessage = Plugin.Config.Configuration().KillstreakMessages;
|
var killstreakMessage = Plugin.Config.Configuration().KillstreakMessages;
|
||||||
var deathstreakMessage = Plugin.Config.Configuration().DeathstreakMessages;
|
var deathstreakMessage = Plugin.Config.Configuration().DeathstreakMessages;
|
||||||
|
|
||||||
string message = killstreakMessage.FirstOrDefault(m => m.Count == killStreak)?.Message;
|
string message = killstreakMessage?.FirstOrDefault(m => m.Count == killStreak)?.Message;
|
||||||
message = message ?? deathstreakMessage.FirstOrDefault(m => m.Count == deathStreak)?.Message;
|
message = message ?? deathstreakMessage?.FirstOrDefault(m => m.Count == deathStreak)?.Message;
|
||||||
return message ?? "";
|
return message ?? "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,6 @@ using IW4MAdmin.Plugins.Stats.Helpers;
|
|||||||
using IW4MAdmin.Plugins.Stats.Models;
|
using IW4MAdmin.Plugins.Stats.Models;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using SharedLibraryCore;
|
using SharedLibraryCore;
|
||||||
using SharedLibraryCore.Configuration;
|
|
||||||
using SharedLibraryCore.Database;
|
using SharedLibraryCore.Database;
|
||||||
using SharedLibraryCore.Database.Models;
|
using SharedLibraryCore.Database.Models;
|
||||||
using SharedLibraryCore.Dtos;
|
using SharedLibraryCore.Dtos;
|
||||||
@ -13,7 +12,6 @@ using SharedLibraryCore.Services;
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace IW4MAdmin.Plugins.Stats
|
namespace IW4MAdmin.Plugins.Stats
|
||||||
@ -28,12 +26,17 @@ namespace IW4MAdmin.Plugins.Stats
|
|||||||
|
|
||||||
public static StatManager Manager { get; private set; }
|
public static StatManager Manager { get; private set; }
|
||||||
public static IManager ServerManager;
|
public static IManager ServerManager;
|
||||||
public static BaseConfigurationHandler<StatsConfiguration> Config { get; private set; }
|
public static IConfigurationHandler<StatsConfiguration> Config { get; private set; }
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
int scriptDamageCount;
|
int scriptDamageCount;
|
||||||
int scriptKillCount;
|
int scriptKillCount;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
public Plugin(IConfigurationHandlerFactory configurationHandlerFactory)
|
||||||
|
{
|
||||||
|
Config = configurationHandlerFactory.GetConfigurationHandler<StatsConfiguration>("StatsPluginSettings");
|
||||||
|
}
|
||||||
|
|
||||||
public async Task OnEventAsync(GameEvent E, Server S)
|
public async Task OnEventAsync(GameEvent E, Server S)
|
||||||
{
|
{
|
||||||
switch (E.Type)
|
switch (E.Type)
|
||||||
@ -53,16 +56,16 @@ namespace IW4MAdmin.Plugins.Stats
|
|||||||
if (!string.IsNullOrEmpty(E.Data) &&
|
if (!string.IsNullOrEmpty(E.Data) &&
|
||||||
E.Origin.ClientId > 1)
|
E.Origin.ClientId > 1)
|
||||||
{
|
{
|
||||||
await Manager.AddMessageAsync(E.Origin.ClientId, StatManager.GetIdForServer(E.Owner), E.Data);
|
await Manager.AddMessageAsync(E.Origin.ClientId, StatManager.GetIdForServer(S), E.Data);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GameEvent.EventType.MapChange:
|
case GameEvent.EventType.MapChange:
|
||||||
Manager.SetTeamBased(StatManager.GetIdForServer(E.Owner), E.Owner.Gametype != "dm");
|
Manager.SetTeamBased(StatManager.GetIdForServer(S), S.Gametype != "dm");
|
||||||
Manager.ResetKillstreaks(E.Owner);
|
Manager.ResetKillstreaks(S);
|
||||||
await Manager.Sync(E.Owner);
|
await Manager.Sync(S);
|
||||||
break;
|
break;
|
||||||
case GameEvent.EventType.MapEnd:
|
case GameEvent.EventType.MapEnd:
|
||||||
await Manager.Sync(E.Owner);
|
await Manager.Sync(S);
|
||||||
break;
|
break;
|
||||||
case GameEvent.EventType.JoinTeam:
|
case GameEvent.EventType.JoinTeam:
|
||||||
break;
|
break;
|
||||||
@ -82,7 +85,7 @@ namespace IW4MAdmin.Plugins.Stats
|
|||||||
break;
|
break;
|
||||||
case GameEvent.EventType.ScriptKill:
|
case GameEvent.EventType.ScriptKill:
|
||||||
string[] killInfo = (E.Data != null) ? E.Data.Split(';') : new string[0];
|
string[] killInfo = (E.Data != null) ? E.Data.Split(';') : new string[0];
|
||||||
if ((E.Owner.CustomCallback || ShouldOverrideAnticheatSetting(E.Owner)) && killInfo.Length >= 18 && !ShouldIgnoreEvent(E.Origin, E.Target))
|
if ((S.CustomCallback || ShouldOverrideAnticheatSetting(S)) && killInfo.Length >= 18 && !ShouldIgnoreEvent(E.Origin, E.Target))
|
||||||
{
|
{
|
||||||
// this treats "world" damage as self damage
|
// this treats "world" damage as self damage
|
||||||
if (IsWorldDamage(E.Origin))
|
if (IsWorldDamage(E.Origin))
|
||||||
@ -95,7 +98,7 @@ namespace IW4MAdmin.Plugins.Stats
|
|||||||
S.Logger.WriteInfo($"Start ScriptKill {scriptKillCount}");
|
S.Logger.WriteInfo($"Start ScriptKill {scriptKillCount}");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
await Manager.AddScriptHit(false, E.Time, E.Origin, E.Target, StatManager.GetIdForServer(E.Owner), S.CurrentMap.Name, killInfo[7], killInfo[8],
|
await Manager.AddScriptHit(false, E.Time, E.Origin, E.Target, StatManager.GetIdForServer(S), S.CurrentMap.Name, killInfo[7], killInfo[8],
|
||||||
killInfo[5], killInfo[6], killInfo[3], killInfo[4], killInfo[9], killInfo[10], killInfo[11], killInfo[12], killInfo[13], killInfo[14], killInfo[15], killInfo[16], killInfo[17]);
|
killInfo[5], killInfo[6], killInfo[3], killInfo[4], killInfo[9], killInfo[10], killInfo[11], killInfo[12], killInfo[13], killInfo[14], killInfo[15], killInfo[16], killInfo[17]);
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
@ -105,7 +108,7 @@ namespace IW4MAdmin.Plugins.Stats
|
|||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
E.Owner.Logger.WriteDebug("Skipping script kill as it is ignored or data in customcallbacks is outdated/missing");
|
S.Logger.WriteDebug("Skipping script kill as it is ignored or data in customcallbacks is outdated/missing");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GameEvent.EventType.Kill:
|
case GameEvent.EventType.Kill:
|
||||||
@ -129,12 +132,12 @@ namespace IW4MAdmin.Plugins.Stats
|
|||||||
E.Origin = E.Target;
|
E.Origin = E.Target;
|
||||||
}
|
}
|
||||||
|
|
||||||
Manager.AddDamageEvent(E.Data, E.Origin.ClientId, E.Target.ClientId, StatManager.GetIdForServer(E.Owner));
|
Manager.AddDamageEvent(E.Data, E.Origin.ClientId, E.Target.ClientId, StatManager.GetIdForServer(S));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GameEvent.EventType.ScriptDamage:
|
case GameEvent.EventType.ScriptDamage:
|
||||||
killInfo = (E.Data != null) ? E.Data.Split(';') : new string[0];
|
killInfo = (E.Data != null) ? E.Data.Split(';') : new string[0];
|
||||||
if ((E.Owner.CustomCallback || ShouldOverrideAnticheatSetting(E.Owner)) && killInfo.Length >= 18 && !ShouldIgnoreEvent(E.Origin, E.Target))
|
if ((S.CustomCallback || ShouldOverrideAnticheatSetting(S)) && killInfo.Length >= 18 && !ShouldIgnoreEvent(E.Origin, E.Target))
|
||||||
{
|
{
|
||||||
// this treats "world" damage as self damage
|
// this treats "world" damage as self damage
|
||||||
if (IsWorldDamage(E.Origin))
|
if (IsWorldDamage(E.Origin))
|
||||||
@ -147,7 +150,7 @@ namespace IW4MAdmin.Plugins.Stats
|
|||||||
S.Logger.WriteInfo($"Start ScriptDamage {scriptDamageCount}");
|
S.Logger.WriteInfo($"Start ScriptDamage {scriptDamageCount}");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
await Manager.AddScriptHit(true, E.Time, E.Origin, E.Target, StatManager.GetIdForServer(E.Owner), S.CurrentMap.Name, killInfo[7], killInfo[8],
|
await Manager.AddScriptHit(true, E.Time, E.Origin, E.Target, StatManager.GetIdForServer(S), S.CurrentMap.Name, killInfo[7], killInfo[8],
|
||||||
killInfo[5], killInfo[6], killInfo[3], killInfo[4], killInfo[9], killInfo[10], killInfo[11], killInfo[12], killInfo[13], killInfo[14], killInfo[15], killInfo[16], killInfo[17]);
|
killInfo[5], killInfo[6], killInfo[3], killInfo[4], killInfo[9], killInfo[10], killInfo[11], killInfo[12], killInfo[13], killInfo[14], killInfo[15], killInfo[16], killInfo[17]);
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
@ -157,7 +160,7 @@ namespace IW4MAdmin.Plugins.Stats
|
|||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
E.Owner.Logger.WriteDebug("Skipping script damage as it is ignored or data in customcallbacks is outdated/missing");
|
S.Logger.WriteDebug("Skipping script damage as it is ignored or data in customcallbacks is outdated/missing");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -166,7 +169,6 @@ namespace IW4MAdmin.Plugins.Stats
|
|||||||
public async Task OnLoadAsync(IManager manager)
|
public async Task OnLoadAsync(IManager manager)
|
||||||
{
|
{
|
||||||
// load custom configuration
|
// load custom configuration
|
||||||
Config = new BaseConfigurationHandler<StatsConfiguration>("StatsPluginSettings");
|
|
||||||
if (Config.Configuration() == null)
|
if (Config.Configuration() == null)
|
||||||
{
|
{
|
||||||
Config.Set((StatsConfiguration)new StatsConfiguration().Generate());
|
Config.Set((StatsConfiguration)new StatsConfiguration().Generate());
|
||||||
@ -518,7 +520,7 @@ namespace IW4MAdmin.Plugins.Stats
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
private bool ShouldIgnoreEvent(EFClient origin, EFClient target)
|
private bool ShouldIgnoreEvent(EFClient origin, EFClient target)
|
||||||
{
|
{
|
||||||
return ((origin?.NetworkId == 1 && target?.NetworkId == 1) || (origin?.ClientId <= 1 && target?.ClientId <= 1));
|
return ((origin?.NetworkId == 1 && target?.NetworkId == 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="RaidMax.IW4MAdmin.SharedLibraryCore" Version="2.2.6" PrivateAssets="All" />
|
<PackageReference Include="RaidMax.IW4MAdmin.SharedLibraryCore" Version="2.2.7" PrivateAssets="All" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
|
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using IW4MAdmin.Application;
|
using IW4MAdmin.Application;
|
||||||
|
using IW4MAdmin.Application.Misc;
|
||||||
using SharedLibraryCore.Configuration;
|
using SharedLibraryCore.Configuration;
|
||||||
using SharedLibraryCore.Interfaces;
|
using SharedLibraryCore.Interfaces;
|
||||||
using System;
|
using System;
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using SharedLibraryCore.Database.Models;
|
using SharedLibraryCore.Database.Models;
|
||||||
|
using SharedLibraryCore.Interfaces;
|
||||||
using SharedLibraryCore.RCon;
|
using SharedLibraryCore.RCon;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@ -14,7 +15,7 @@ namespace Tests
|
|||||||
|
|
||||||
public override string Version => "test";
|
public override string Version => "test";
|
||||||
|
|
||||||
public override async Task<(List<EFClient>, string)> GetStatusAsync(Connection connection)
|
public override async Task<(List<EFClient>, string)> GetStatusAsync(IRConConnection connection)
|
||||||
{
|
{
|
||||||
var clientList = new List<EFClient>();
|
var clientList = new List<EFClient>();
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
<RunPostBuildEvent>Always</RunPostBuildEvent>
|
<RunPostBuildEvent>Always</RunPostBuildEvent>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="RaidMax.IW4MAdmin.SharedLibraryCore" Version="2.2.6" PrivateAssets="All" />
|
<PackageReference Include="RaidMax.IW4MAdmin.SharedLibraryCore" Version="2.2.7" PrivateAssets="All" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -64,16 +64,19 @@ namespace IW4MAdmin.Plugins.Welcome
|
|||||||
|
|
||||||
public string Name => "Welcome Plugin";
|
public string Name => "Welcome Plugin";
|
||||||
|
|
||||||
private BaseConfigurationHandler<WelcomeConfiguration> Config;
|
private readonly IConfigurationHandler<WelcomeConfiguration> _configHandler;
|
||||||
|
|
||||||
|
public Plugin(IConfigurationHandlerFactory configurationHandlerFactory)
|
||||||
|
{
|
||||||
|
_configHandler = configurationHandlerFactory.GetConfigurationHandler<WelcomeConfiguration>("WelcomePluginSettings");
|
||||||
|
}
|
||||||
|
|
||||||
public async Task OnLoadAsync(IManager manager)
|
public async Task OnLoadAsync(IManager manager)
|
||||||
{
|
{
|
||||||
// load custom configuration
|
if (_configHandler.Configuration() == null)
|
||||||
Config = new BaseConfigurationHandler<WelcomeConfiguration>("WelcomePluginSettings");
|
|
||||||
if (Config.Configuration() == null)
|
|
||||||
{
|
{
|
||||||
Config.Set((WelcomeConfiguration)new WelcomeConfiguration().Generate());
|
_configHandler.Set((WelcomeConfiguration)new WelcomeConfiguration().Generate());
|
||||||
await Config.Save();
|
await _configHandler.Save();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,9 +90,9 @@ namespace IW4MAdmin.Plugins.Welcome
|
|||||||
{
|
{
|
||||||
EFClient newPlayer = E.Origin;
|
EFClient newPlayer = E.Origin;
|
||||||
if (newPlayer.Level >= Permission.Trusted && !E.Origin.Masked)
|
if (newPlayer.Level >= Permission.Trusted && !E.Origin.Masked)
|
||||||
E.Owner.Broadcast(await ProcessAnnouncement(Config.Configuration().PrivilegedAnnouncementMessage, newPlayer));
|
E.Owner.Broadcast(await ProcessAnnouncement(_configHandler.Configuration().PrivilegedAnnouncementMessage, newPlayer));
|
||||||
|
|
||||||
newPlayer.Tell(await ProcessAnnouncement(Config.Configuration().UserWelcomeMessage, newPlayer));
|
newPlayer.Tell(await ProcessAnnouncement(_configHandler.Configuration().UserWelcomeMessage, newPlayer));
|
||||||
|
|
||||||
if (newPlayer.Level == Permission.Flagged)
|
if (newPlayer.Level == Permission.Flagged)
|
||||||
{
|
{
|
||||||
@ -107,7 +110,7 @@ namespace IW4MAdmin.Plugins.Welcome
|
|||||||
E.Owner.ToAdmins($"^1NOTICE: ^7Flagged player ^5{newPlayer.Name} ^7({penaltyReason}) has joined!");
|
E.Owner.ToAdmins($"^1NOTICE: ^7Flagged player ^5{newPlayer.Name} ^7({penaltyReason}) has joined!");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
E.Owner.Broadcast(await ProcessAnnouncement(Config.Configuration().UserAnnouncementMessage, newPlayer));
|
E.Owner.Broadcast(await ProcessAnnouncement(_configHandler.Configuration().UserAnnouncementMessage, newPlayer));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="RaidMax.IW4MAdmin.SharedLibraryCore" Version="2.2.6" PrivateAssets="All" />
|
<PackageReference Include="RaidMax.IW4MAdmin.SharedLibraryCore" Version="2.2.7" PrivateAssets="All" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
|
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
|
||||||
|
@ -500,18 +500,18 @@ namespace SharedLibraryCore.Commands
|
|||||||
|
|
||||||
public override Task ExecuteAsync(GameEvent E)
|
public override Task ExecuteAsync(GameEvent E)
|
||||||
{
|
{
|
||||||
String cmd = E.Data.Trim();
|
string cmd = E.Data.Trim();
|
||||||
|
|
||||||
if (cmd.Length > 2)
|
if (cmd.Length > 2)
|
||||||
{
|
{
|
||||||
bool found = false;
|
bool found = false;
|
||||||
foreach (Command C in E.Owner.Manager.GetCommands())
|
foreach (var command in E.Owner.Manager.GetCommands())
|
||||||
{
|
{
|
||||||
if (C.Name == cmd.ToLower() ||
|
if (command.Name == cmd.ToLower() ||
|
||||||
C.Alias == cmd.ToLower())
|
command.Alias == cmd.ToLower())
|
||||||
{
|
{
|
||||||
E.Origin.Tell($"[^3{C.Name}^7] {C.Description}");
|
E.Origin.Tell($"[^3{command.Name}^7] {command.Description}");
|
||||||
E.Origin.Tell(C.Syntax);
|
E.Origin.Tell(command.Syntax);
|
||||||
found = true;
|
found = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -56,11 +56,11 @@ namespace SharedLibraryCore.Configuration
|
|||||||
{
|
{
|
||||||
var loc = Utilities.CurrentLocalization.LocalizationIndex;
|
var loc = Utilities.CurrentLocalization.LocalizationIndex;
|
||||||
var parserVersions = rconParsers.Select(_parser => _parser.Name).ToArray();
|
var parserVersions = rconParsers.Select(_parser => _parser.Name).ToArray();
|
||||||
var selection = Utilities.PromptSelection($"{loc["SETUP_SERVER_RCON_PARSER_VERSION"]} ({IPAddress}:{Port})", $"{loc["SETUP_PROMPT_DEFAULT"]} (Call of Duty)", null, parserVersions);
|
var selection = Utilities.PromptSelection($"{loc["SETUP_SERVER_RCON_PARSER_VERSION"]} ({IPAddress}:{Port})", parserVersions[0], null, parserVersions);
|
||||||
|
|
||||||
if (selection.Item1 >= 0)
|
if (selection.Item1 >= 0)
|
||||||
{
|
{
|
||||||
RConParserVersion = rconParsers.First(_parser => _parser.Name == selection.Item2).Version;
|
RConParserVersion = rconParsers.FirstOrDefault(_parser => _parser.Name == selection.Item2)?.Version;
|
||||||
|
|
||||||
if (selection.Item1 > 0 && !rconParsers[selection.Item1 - 1].CanGenerateLogPath)
|
if (selection.Item1 > 0 && !rconParsers[selection.Item1 - 1].CanGenerateLogPath)
|
||||||
{
|
{
|
||||||
@ -70,11 +70,11 @@ namespace SharedLibraryCore.Configuration
|
|||||||
}
|
}
|
||||||
|
|
||||||
parserVersions = eventParsers.Select(_parser => _parser.Name).ToArray();
|
parserVersions = eventParsers.Select(_parser => _parser.Name).ToArray();
|
||||||
selection = Utilities.PromptSelection($"{loc["SETUP_SERVER_EVENT_PARSER_VERSION"]} ({IPAddress}:{Port})", $"{loc["SETUP_PROMPT_DEFAULT"]} (Call of Duty)", null, parserVersions);
|
selection = Utilities.PromptSelection($"{loc["SETUP_SERVER_EVENT_PARSER_VERSION"]} ({IPAddress}:{Port})", parserVersions[0], null, parserVersions);
|
||||||
|
|
||||||
if (selection.Item1 >= 0)
|
if (selection.Item1 >= 0)
|
||||||
{
|
{
|
||||||
EventParserVersion = eventParsers.First(_parser => _parser.Name == selection.Item2).Version;
|
EventParserVersion = eventParsers.FirstOrDefault(_parser => _parser.Name == selection.Item2)?.Version;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,12 +26,6 @@ namespace SharedLibraryCore.Configuration.Validation
|
|||||||
RuleForEach(_server => _server.AutoMessages)
|
RuleForEach(_server => _server.AutoMessages)
|
||||||
.NotEmpty();
|
.NotEmpty();
|
||||||
|
|
||||||
RuleFor(_server => _server.RConParserVersion)
|
|
||||||
.NotEmpty();
|
|
||||||
|
|
||||||
RuleFor(_server => _server.EventParserVersion)
|
|
||||||
.NotEmpty();
|
|
||||||
|
|
||||||
RuleFor(_server => _server.ReservedSlotNumber)
|
RuleFor(_server => _server.ReservedSlotNumber)
|
||||||
.InclusiveBetween(0, 32);
|
.InclusiveBetween(0, 32);
|
||||||
}
|
}
|
||||||
|
14
SharedLibraryCore/Interfaces/IBasePathProvider.cs
Normal file
14
SharedLibraryCore/Interfaces/IBasePathProvider.cs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
namespace SharedLibraryCore.Interfaces
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// defines the capabilities for providing a base path
|
||||||
|
/// unused as of now, will be used later during refactorying
|
||||||
|
/// </summary>
|
||||||
|
public interface IBasePathProvider
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// working directory of IW4MAdmin
|
||||||
|
/// </summary>
|
||||||
|
string BasePath { get; }
|
||||||
|
}
|
||||||
|
}
|
17
SharedLibraryCore/Interfaces/IConfigurationHandlerFactory.cs
Normal file
17
SharedLibraryCore/Interfaces/IConfigurationHandlerFactory.cs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
namespace SharedLibraryCore.Interfaces
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// defines the capabilities of the configuration handler factory
|
||||||
|
/// used to generate new instance of configuration handlers
|
||||||
|
/// </summary>
|
||||||
|
public interface IConfigurationHandlerFactory
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// generates a new configuration handler
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">base configuration type</typeparam>
|
||||||
|
/// <param name="name">file name of configuration</param>
|
||||||
|
/// <returns>new configuration handler instance</returns>
|
||||||
|
IConfigurationHandler<T> GetConfigurationHandler<T>(string name) where T : IBaseConfiguration;
|
||||||
|
}
|
||||||
|
}
|
18
SharedLibraryCore/Interfaces/IGameServerInstanceFactory.cs
Normal file
18
SharedLibraryCore/Interfaces/IGameServerInstanceFactory.cs
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
using SharedLibraryCore.Configuration;
|
||||||
|
|
||||||
|
namespace SharedLibraryCore.Interfaces
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// defines the capabilities of game server instance factory
|
||||||
|
/// </summary>
|
||||||
|
public interface IGameServerInstanceFactory
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// creates the instance of a game server
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="config">server configuration</param>
|
||||||
|
/// <param name="manager">application manager</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Server CreateServer(ServerConfiguration config, IManager manager);
|
||||||
|
}
|
||||||
|
}
|
@ -2,7 +2,6 @@
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using SharedLibraryCore.Services;
|
using SharedLibraryCore.Services;
|
||||||
using SharedLibraryCore.Configuration;
|
using SharedLibraryCore.Configuration;
|
||||||
using System.Reflection;
|
|
||||||
using SharedLibraryCore.Database.Models;
|
using SharedLibraryCore.Database.Models;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
@ -29,7 +28,10 @@ namespace SharedLibraryCore.Interfaces
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>EventHandler for the manager</returns>
|
/// <returns>EventHandler for the manager</returns>
|
||||||
IEventHandler GetEventHandler();
|
IEventHandler GetEventHandler();
|
||||||
IList<Assembly> GetPluginAssemblies();
|
/// <summary>
|
||||||
|
/// enumerates the registered plugin instances
|
||||||
|
/// </summary>
|
||||||
|
IEnumerable<IPlugin> Plugins { get; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// provides a page list to add and remove from
|
/// provides a page list to add and remove from
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -1,32 +1,23 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Reflection;
|
|
||||||
|
|
||||||
namespace SharedLibraryCore.Interfaces
|
namespace SharedLibraryCore.Interfaces
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Defines the capabilities of the plugin importer
|
/// defines the capabilities of the plugin importer
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IPluginImporter
|
public interface IPluginImporter
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Command types that are defined in plugin assemblies
|
/// discovers C# assembly plugin and command types
|
||||||
/// </summary>
|
/// </summary>
|
||||||
IList<Type> CommandTypes { get; }
|
/// <returns>tuple of IPlugin implementation type definitions, and IManagerCommand type definitions</returns>
|
||||||
|
(IEnumerable<Type>, IEnumerable<Type>) DiscoverAssemblyPluginImplementations();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The loaded plugins from plugin assemblies
|
/// discovers the script plugins
|
||||||
/// </summary>
|
/// </summary>
|
||||||
IList<IPlugin> ActivePlugins { get; }
|
/// <returns>initialized script plugin collection</returns>
|
||||||
|
IEnumerable<IPlugin> DiscoverScriptPlugins();
|
||||||
/// <summary>
|
|
||||||
/// Assemblies that contain plugins
|
|
||||||
/// </summary>
|
|
||||||
IList<Assembly> PluginAssemblies { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// All assemblies in the plugin folder
|
|
||||||
/// </summary>
|
|
||||||
IList<Assembly> Assemblies { get; }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
25
SharedLibraryCore/Interfaces/IRConConnection.cs
Normal file
25
SharedLibraryCore/Interfaces/IRConConnection.cs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
using SharedLibraryCore.RCon;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace SharedLibraryCore.Interfaces
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// defines the capabilities of an RCon connection
|
||||||
|
/// </summary>
|
||||||
|
public interface IRConConnection
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// sends a query with the instance of the rcon connection
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="type">type of RCon query to perform</param>
|
||||||
|
/// <param name="parameters">optional parameter list</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<string[]> SendQueryAsync(StaticHelpers.QueryType type, string parameters = "");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// sets the rcon parser configuration
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="config">parser config</param>
|
||||||
|
void SetConfiguration(IRConParserConfiguration config);
|
||||||
|
}
|
||||||
|
}
|
17
SharedLibraryCore/Interfaces/IRConConnectionFactory.cs
Normal file
17
SharedLibraryCore/Interfaces/IRConConnectionFactory.cs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
namespace SharedLibraryCore.Interfaces
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// defines the capabilities of an RCon connection factory
|
||||||
|
/// </summary>
|
||||||
|
public interface IRConConnectionFactory
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// creates an rcon connection instance
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="ipAddress">ip address of the server</param>
|
||||||
|
/// <param name="port">port of the server</param>
|
||||||
|
/// <param name="password"> password of the server</param>
|
||||||
|
/// <returns>instance of rcon connection</returns>
|
||||||
|
IRConConnection CreateConnection(string ipAddress, int port, string password);
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,6 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using SharedLibraryCore.Database.Models;
|
using SharedLibraryCore.Database.Models;
|
||||||
using SharedLibraryCore.RCon;
|
|
||||||
using static SharedLibraryCore.Server;
|
using static SharedLibraryCore.Server;
|
||||||
|
|
||||||
namespace SharedLibraryCore.Interfaces
|
namespace SharedLibraryCore.Interfaces
|
||||||
@ -15,7 +14,7 @@ namespace SharedLibraryCore.Interfaces
|
|||||||
/// <param name="connection">RCon connection to retrieve with</param>
|
/// <param name="connection">RCon connection to retrieve with</param>
|
||||||
/// <param name="dvarName">name of DVAR</param>
|
/// <param name="dvarName">name of DVAR</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<Dvar<T>> GetDvarAsync<T>(Connection connection, string dvarName);
|
Task<Dvar<T>> GetDvarAsync<T>(IRConConnection connection, string dvarName);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// set value of DVAR by name
|
/// set value of DVAR by name
|
||||||
@ -24,7 +23,7 @@ namespace SharedLibraryCore.Interfaces
|
|||||||
/// <param name="dvarName">name of DVAR to set</param>
|
/// <param name="dvarName">name of DVAR to set</param>
|
||||||
/// <param name="dvarValue">value to set DVAR to</param>
|
/// <param name="dvarValue">value to set DVAR to</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<bool> SetDvarAsync(Connection connection, string dvarName, object dvarValue);
|
Task<bool> SetDvarAsync(IRConConnection connection, string dvarName, object dvarValue);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// executes a console command on the server
|
/// executes a console command on the server
|
||||||
@ -32,14 +31,14 @@ namespace SharedLibraryCore.Interfaces
|
|||||||
/// <param name="connection">RCon connection to use</param>
|
/// <param name="connection">RCon connection to use</param>
|
||||||
/// <param name="command">console command to execute</param>
|
/// <param name="command">console command to execute</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<string[]> ExecuteCommandAsync(Connection connection, string command);
|
Task<string[]> ExecuteCommandAsync(IRConConnection connection, string command);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// get the list of connected clients from status response
|
/// get the list of connected clients from status response
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="connection">RCon connection to use</param>
|
/// <param name="connection">RCon connection to use</param>
|
||||||
/// <returns>list of clients, and current map</returns>
|
/// <returns>list of clients, and current map</returns>
|
||||||
Task<(List<EFClient>, string)> GetStatusAsync(Connection connection);
|
Task<(List<EFClient>, string)> GetStatusAsync(IRConConnection connection);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// stores the RCon configuration
|
/// stores the RCon configuration
|
||||||
|
@ -1,8 +1,4 @@
|
|||||||
using System;
|
namespace SharedLibraryCore.RCon
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace SharedLibraryCore.RCon
|
|
||||||
{
|
{
|
||||||
public class CommandPrefix
|
public class CommandPrefix
|
||||||
{
|
{
|
||||||
|
@ -28,7 +28,7 @@ namespace SharedLibraryCore
|
|||||||
T7 = 8
|
T7 = 8
|
||||||
}
|
}
|
||||||
|
|
||||||
public Server(IManager mgr, ServerConfiguration config)
|
public Server(IManager mgr, IRConConnectionFactory rconConnectionFactory, ServerConfiguration config)
|
||||||
{
|
{
|
||||||
Password = config.Password;
|
Password = config.Password;
|
||||||
IP = config.IPAddress;
|
IP = config.IPAddress;
|
||||||
@ -37,8 +37,7 @@ namespace SharedLibraryCore
|
|||||||
Logger = Manager.GetLogger(this.EndPoint);
|
Logger = Manager.GetLogger(this.EndPoint);
|
||||||
Logger.WriteInfo(this.ToString());
|
Logger.WriteInfo(this.ToString());
|
||||||
ServerConfig = config;
|
ServerConfig = config;
|
||||||
RemoteConnection = new RCon.Connection(IP, Port, Password, Logger, null);
|
RemoteConnection = rconConnectionFactory.CreateConnection(IP, Port, Password);
|
||||||
|
|
||||||
EventProcessing = new SemaphoreSlim(1, 1);
|
EventProcessing = new SemaphoreSlim(1, 1);
|
||||||
Clients = new List<EFClient>(new EFClient[18]);
|
Clients = new List<EFClient>(new EFClient[18]);
|
||||||
Reports = new List<Report>();
|
Reports = new List<Report>();
|
||||||
@ -283,7 +282,7 @@ namespace SharedLibraryCore
|
|||||||
public IManager Manager { get; protected set; }
|
public IManager Manager { get; protected set; }
|
||||||
public ILogger Logger { get; private set; }
|
public ILogger Logger { get; private set; }
|
||||||
public ServerConfiguration ServerConfig { get; private set; }
|
public ServerConfiguration ServerConfig { get; private set; }
|
||||||
public List<Map> Maps { get; protected set; }
|
public List<Map> Maps { get; protected set; } = new List<Map>();
|
||||||
public List<Report> Reports { get; set; }
|
public List<Report> Reports { get; set; }
|
||||||
public List<ChatInfo> ChatHistory { get; protected set; }
|
public List<ChatInfo> ChatHistory { get; protected set; }
|
||||||
public Queue<PlayerHistory> ClientHistory { get; private set; }
|
public Queue<PlayerHistory> ClientHistory { get; private set; }
|
||||||
@ -307,7 +306,7 @@ namespace SharedLibraryCore
|
|||||||
public bool Throttled { get; protected set; }
|
public bool Throttled { get; protected set; }
|
||||||
public bool CustomCallback { get; protected set; }
|
public bool CustomCallback { get; protected set; }
|
||||||
public string WorkingDirectory { get; protected set; }
|
public string WorkingDirectory { get; protected set; }
|
||||||
public RCon.Connection RemoteConnection { get; protected set; }
|
public IRConConnection RemoteConnection { get; protected set; }
|
||||||
public IRConParser RconParser { get; protected set; }
|
public IRConParser RconParser { get; protected set; }
|
||||||
public IEventParser EventParser { get; set; }
|
public IEventParser EventParser { get; set; }
|
||||||
public string LogPath { get; protected set; }
|
public string LogPath { get; protected set; }
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
<ApplicationIcon />
|
<ApplicationIcon />
|
||||||
<StartupObject />
|
<StartupObject />
|
||||||
<PackageId>RaidMax.IW4MAdmin.SharedLibraryCore</PackageId>
|
<PackageId>RaidMax.IW4MAdmin.SharedLibraryCore</PackageId>
|
||||||
<Version>2.2.6</Version>
|
<Version>2.2.7</Version>
|
||||||
<Authors>RaidMax</Authors>
|
<Authors>RaidMax</Authors>
|
||||||
<Company>Forever None</Company>
|
<Company>Forever None</Company>
|
||||||
<Configurations>Debug;Release;Prerelease</Configurations>
|
<Configurations>Debug;Release;Prerelease</Configurations>
|
||||||
@ -20,8 +20,8 @@
|
|||||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||||
<Description>Shared Library for IW4MAdmin</Description>
|
<Description>Shared Library for IW4MAdmin</Description>
|
||||||
<AssemblyVersion>2.2.6.0</AssemblyVersion>
|
<AssemblyVersion>2.2.7.0</AssemblyVersion>
|
||||||
<FileVersion>2.2.6.0</FileVersion>
|
<FileVersion>2.2.7.0</FileVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Prerelease|AnyCPU'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Prerelease|AnyCPU'">
|
||||||
@ -69,6 +69,10 @@
|
|||||||
<PackageReference Include="SimpleCrypto.NetCore" Version="1.0.0" />
|
<PackageReference Include="SimpleCrypto.NetCore" Version="1.0.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup Condition="'$(Configuration)'=='Debug'">
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="3.1.1" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
<Target Name="PreBuild" BeforeTargets="PreBuildEvent">
|
<Target Name="PreBuild" BeforeTargets="PreBuildEvent">
|
||||||
<Exec Command="if not exist "$(ProjectDir)..\BUILD" (
if $(ConfigurationName) == Debug (
md "$(ProjectDir)..\BUILD"
)
)
if not exist "$(ProjectDir)..\BUILD\Plugins" (
if $(ConfigurationName) == Debug (
md "$(ProjectDir)..\BUILD\Plugins"
)
)" />
|
<Exec Command="if not exist "$(ProjectDir)..\BUILD" (
if $(ConfigurationName) == Debug (
md "$(ProjectDir)..\BUILD"
)
)
if not exist "$(ProjectDir)..\BUILD\Plugins" (
if $(ConfigurationName) == Debug (
md "$(ProjectDir)..\BUILD\Plugins"
)
)" />
|
||||||
</Target>
|
</Target>
|
||||||
|
34
Tests/ApplicationTests/ApplicationTests.csproj
Normal file
34
Tests/ApplicationTests/ApplicationTests.csproj
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="FakeItEasy" Version="6.0.0" />
|
||||||
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" />
|
||||||
|
<PackageReference Include="NUnit" Version="3.12.0" />
|
||||||
|
<PackageReference Include="NUnit3TestAdapter" Version="3.16.1">
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
</PackageReference>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\Application\Application.csproj" />
|
||||||
|
<ProjectReference Include="..\..\Plugins\Stats\Stats.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<None Update="Files\T6Game.log">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Files\T6GameStats.log">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Files\T6MapRotation.log">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
85
Tests/ApplicationTests/ServerTests.cs
Normal file
85
Tests/ApplicationTests/ServerTests.cs
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
using FakeItEasy;
|
||||||
|
using IW4MAdmin;
|
||||||
|
using IW4MAdmin.Application;
|
||||||
|
using IW4MAdmin.Application.EventParsers;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using SharedLibraryCore.Interfaces;
|
||||||
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
|
namespace ApplicationTests
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class ServerTests
|
||||||
|
{
|
||||||
|
ILogger logger;
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void Setup()
|
||||||
|
{
|
||||||
|
logger = A.Fake<ILogger>();
|
||||||
|
|
||||||
|
void testLog(string msg) => Console.WriteLine(msg);
|
||||||
|
|
||||||
|
A.CallTo(() => logger.WriteError(A<string>.Ignored)).Invokes((string msg) => testLog(msg));
|
||||||
|
A.CallTo(() => logger.WriteWarning(A<string>.Ignored)).Invokes((string msg) => testLog(msg));
|
||||||
|
A.CallTo(() => logger.WriteInfo(A<string>.Ignored)).Invokes((string msg) => testLog(msg));
|
||||||
|
A.CallTo(() => logger.WriteDebug(A<string>.Ignored)).Invokes((string msg) => testLog(msg));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void GameTimeFalseQuitTest()
|
||||||
|
{
|
||||||
|
var mgr = A.Fake<IManager>();
|
||||||
|
var server = new IW4MServer(mgr,
|
||||||
|
new SharedLibraryCore.Configuration.ServerConfiguration() { IPAddress = "127.0.0.1", Port = 28960 },
|
||||||
|
A.Fake<ITranslationLookup>(), A.Fake<IRConConnectionFactory>());
|
||||||
|
|
||||||
|
var parser = new BaseEventParser();
|
||||||
|
parser.Configuration.GuidNumberStyle = System.Globalization.NumberStyles.Integer;
|
||||||
|
|
||||||
|
var log = System.IO.File.ReadAllLines("Files\\T6MapRotation.log");
|
||||||
|
foreach (string line in log)
|
||||||
|
{
|
||||||
|
var e = parser.GenerateGameEvent(line);
|
||||||
|
if (e.Origin != null)
|
||||||
|
{
|
||||||
|
e.Origin.CurrentServer = server;
|
||||||
|
}
|
||||||
|
|
||||||
|
server.ExecuteEvent(e).Wait();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void LogFileReplay()
|
||||||
|
{
|
||||||
|
var mgr = A.Fake<IManager>();
|
||||||
|
A.CallTo(() => mgr.GetLogger(A<long>.Ignored)).Returns(logger);
|
||||||
|
|
||||||
|
var server = new IW4MServer(mgr,
|
||||||
|
new SharedLibraryCore.Configuration.ServerConfiguration() { IPAddress = "127.0.0.1", Port = 28960 },
|
||||||
|
A.Fake<ITranslationLookup>(), A.Fake<IRConConnectionFactory>());
|
||||||
|
|
||||||
|
var parser = new BaseEventParser();
|
||||||
|
parser.Configuration.GuidNumberStyle = System.Globalization.NumberStyles.Integer;
|
||||||
|
|
||||||
|
var log = System.IO.File.ReadAllLines("Files\\T6Game.log");
|
||||||
|
long lastEventId = 0;
|
||||||
|
foreach (string line in log)
|
||||||
|
{
|
||||||
|
var e = parser.GenerateGameEvent(line);
|
||||||
|
server.Logger.WriteInfo($"{e.GameTime}");
|
||||||
|
if (e.Origin != null)
|
||||||
|
{
|
||||||
|
e.Origin.CurrentServer = server;
|
||||||
|
}
|
||||||
|
|
||||||
|
server.ExecuteEvent(e).Wait();
|
||||||
|
lastEventId = e.Id;
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert.GreaterOrEqual(lastEventId, log.Length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
117
Tests/ApplicationTests/StatsTests.cs
Normal file
117
Tests/ApplicationTests/StatsTests.cs
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
using NUnit.Framework;
|
||||||
|
using System;
|
||||||
|
using SharedLibraryCore.Interfaces;
|
||||||
|
using IW4MAdmin;
|
||||||
|
using FakeItEasy;
|
||||||
|
using IW4MAdmin.Application.EventParsers;
|
||||||
|
using System.Linq;
|
||||||
|
using IW4MAdmin.Plugins.Stats.Models;
|
||||||
|
using IW4MAdmin.Application.Helpers;
|
||||||
|
using IW4MAdmin.Plugins.Stats.Config;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using SharedLibraryCore.Database.Models;
|
||||||
|
|
||||||
|
namespace ApplicationTests
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class StatsTests
|
||||||
|
{
|
||||||
|
ILogger logger;
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void Setup()
|
||||||
|
{
|
||||||
|
logger = A.Fake<ILogger>();
|
||||||
|
|
||||||
|
void testLog(string msg) => Console.WriteLine(msg);
|
||||||
|
|
||||||
|
A.CallTo(() => logger.WriteError(A<string>.Ignored)).Invokes((string msg) => testLog(msg));
|
||||||
|
A.CallTo(() => logger.WriteWarning(A<string>.Ignored)).Invokes((string msg) => testLog(msg));
|
||||||
|
A.CallTo(() => logger.WriteInfo(A<string>.Ignored)).Invokes((string msg) => testLog(msg));
|
||||||
|
A.CallTo(() => logger.WriteDebug(A<string>.Ignored)).Invokes((string msg) => testLog(msg));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestKDR()
|
||||||
|
{
|
||||||
|
var mgr = A.Fake<IManager>();
|
||||||
|
var handlerFactory = A.Fake<IConfigurationHandlerFactory>();
|
||||||
|
var config = A.Fake<IConfigurationHandler<StatsConfiguration>>();
|
||||||
|
var plugin = new IW4MAdmin.Plugins.Stats.Plugin(handlerFactory);
|
||||||
|
|
||||||
|
A.CallTo(() => config.Configuration())
|
||||||
|
.Returns(new StatsConfiguration()
|
||||||
|
{
|
||||||
|
EnableAntiCheat = true
|
||||||
|
});
|
||||||
|
|
||||||
|
A.CallTo(() => handlerFactory.GetConfigurationHandler<StatsConfiguration>(A<string>.Ignored))
|
||||||
|
.Returns(config);
|
||||||
|
|
||||||
|
A.CallTo(() => mgr.GetLogger(A<long>.Ignored))
|
||||||
|
.Returns(logger);
|
||||||
|
|
||||||
|
var server = new IW4MServer(mgr,
|
||||||
|
new SharedLibraryCore.Configuration.ServerConfiguration() { IPAddress = "127.0.0.1", Port = 28960 },
|
||||||
|
A.Fake<ITranslationLookup>(),
|
||||||
|
A.Fake<IRConConnectionFactory>());
|
||||||
|
|
||||||
|
var parser = new BaseEventParser();
|
||||||
|
parser.Configuration.GuidNumberStyle = System.Globalization.NumberStyles.Integer;
|
||||||
|
|
||||||
|
var log = System.IO.File.ReadAllLines("Files\\T6GameStats.log");
|
||||||
|
plugin.OnLoadAsync(mgr).Wait();
|
||||||
|
plugin.OnEventAsync(new SharedLibraryCore.GameEvent() { Type = SharedLibraryCore.GameEvent.EventType.Start, Owner = server }, server).Wait();
|
||||||
|
|
||||||
|
var clientList = new Dictionary<long, EFClient>();
|
||||||
|
|
||||||
|
foreach (string line in log)
|
||||||
|
{
|
||||||
|
var e = parser.GenerateGameEvent(line);
|
||||||
|
if (e.Origin != null)
|
||||||
|
{
|
||||||
|
//if (!clientList.ContainsKey(e.Origin.NetworkId))
|
||||||
|
//{
|
||||||
|
// clientList.Add(e.Origin.NetworkId, e.Origin);
|
||||||
|
//}
|
||||||
|
|
||||||
|
//else
|
||||||
|
//{
|
||||||
|
// e.Origin = clientList[e.Origin.NetworkId];
|
||||||
|
//}
|
||||||
|
|
||||||
|
e.Origin = server.GetClientsAsList().FirstOrDefault(_client => _client.NetworkId == e.Origin.NetworkId) ?? e.Origin;
|
||||||
|
e.Origin.CurrentServer = server;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.Target != null)
|
||||||
|
{
|
||||||
|
//if (!clientList.ContainsKey(e.Target.NetworkId))
|
||||||
|
//{
|
||||||
|
// clientList.Add(e.Target.NetworkId, e.Target);
|
||||||
|
//}
|
||||||
|
|
||||||
|
//else
|
||||||
|
//{
|
||||||
|
// e.Target = clientList[e.Target.NetworkId];
|
||||||
|
//}
|
||||||
|
|
||||||
|
e.Target = server.GetClientsAsList().FirstOrDefault(_client => _client.NetworkId == e.Target.NetworkId) ?? e.Target;
|
||||||
|
e.Target.CurrentServer = server;
|
||||||
|
}
|
||||||
|
|
||||||
|
server.ExecuteEvent(e).Wait();
|
||||||
|
plugin.OnEventAsync(e, server).Wait();
|
||||||
|
}
|
||||||
|
|
||||||
|
var client = server.GetClientsAsList().First(_client => _client?.NetworkId == 2028755667);
|
||||||
|
var stats = client.GetAdditionalProperty<EFClientStatistics>("ClientStats");
|
||||||
|
}
|
||||||
|
|
||||||
|
class BasePathProvider : IBasePathProvider
|
||||||
|
{
|
||||||
|
public string BasePath => @"X:\IW4MAdmin\BUILD\Plugins";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -11,11 +11,8 @@ namespace WebfrontCore.Controllers
|
|||||||
{
|
{
|
||||||
public class HomeController : BaseController
|
public class HomeController : BaseController
|
||||||
{
|
{
|
||||||
private readonly IPluginImporter _pluginImporter;
|
public HomeController(IManager manager) : base(manager)
|
||||||
|
|
||||||
public HomeController(IManager manager, IPluginImporter importer) : base(manager)
|
|
||||||
{
|
{
|
||||||
_pluginImporter = importer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IActionResult> Index()
|
public async Task<IActionResult> Index()
|
||||||
@ -68,7 +65,7 @@ namespace WebfrontCore.Controllers
|
|||||||
var pluginType = _cmd.GetType().Assembly.GetTypes().FirstOrDefault(_type => _type.Assembly != excludedAssembly && typeof(IPlugin).IsAssignableFrom(_type));
|
var pluginType = _cmd.GetType().Assembly.GetTypes().FirstOrDefault(_type => _type.Assembly != excludedAssembly && typeof(IPlugin).IsAssignableFrom(_type));
|
||||||
return pluginType == null ?
|
return pluginType == null ?
|
||||||
Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_HELP_COMMAND_NATIVE"] :
|
Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_HELP_COMMAND_NATIVE"] :
|
||||||
_pluginImporter.ActivePlugins.First(_plugin => _plugin.GetType() == pluginType).Name; // for now we're just returning the name of the plugin, maybe later we'll include more info
|
Manager.Plugins.First(_plugin => _plugin.GetType() == pluginType).Name; // for now we're just returning the name of the plugin, maybe later we'll include more info
|
||||||
})
|
})
|
||||||
.Select(_grp => (_grp.Key, _grp.AsEnumerable()));
|
.Select(_grp => (_grp.Key, _grp.AsEnumerable()));
|
||||||
|
|
||||||
|
@ -7,9 +7,14 @@ using Microsoft.AspNetCore.Mvc.Razor;
|
|||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
using SharedLibraryCore;
|
||||||
using SharedLibraryCore.Database;
|
using SharedLibraryCore.Database;
|
||||||
using SharedLibraryCore.Interfaces;
|
using SharedLibraryCore.Interfaces;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
|
using System.Reflection;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using WebfrontCore.Middleware;
|
using WebfrontCore.Middleware;
|
||||||
|
|
||||||
@ -32,20 +37,33 @@ namespace WebfrontCore
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
IEnumerable<Assembly> pluginAssemblies()
|
||||||
|
{
|
||||||
|
string pluginDir = $"{Utilities.OperatingDirectory}Plugins{Path.DirectorySeparatorChar}";
|
||||||
|
|
||||||
|
if (Directory.Exists(pluginDir))
|
||||||
|
{
|
||||||
|
var dllFileNames = Directory.GetFiles($"{Utilities.OperatingDirectory}Plugins{Path.DirectorySeparatorChar}", "*.dll");
|
||||||
|
return dllFileNames.Select(_file => Assembly.LoadFrom(_file));
|
||||||
|
}
|
||||||
|
|
||||||
|
return Enumerable.Empty<Assembly>();
|
||||||
|
}
|
||||||
|
|
||||||
// Add framework services.
|
// Add framework services.
|
||||||
var mvcBuilder = services.AddMvc(_options => _options.SuppressAsyncSuffixInActionNames = false)
|
var mvcBuilder = services.AddMvc(_options => _options.SuppressAsyncSuffixInActionNames = false)
|
||||||
.ConfigureApplicationPartManager(_ =>
|
.ConfigureApplicationPartManager(_partManager =>
|
||||||
{
|
{
|
||||||
foreach (var assembly in Program.Manager.GetPluginAssemblies())
|
foreach (var assembly in pluginAssemblies())
|
||||||
{
|
{
|
||||||
if (assembly.FullName.Contains("Views"))
|
if (assembly.FullName.Contains("Views"))
|
||||||
{
|
{
|
||||||
_.ApplicationParts.Add(new CompiledRazorAssemblyPart(assembly));
|
_partManager.ApplicationParts.Add(new CompiledRazorAssemblyPart(assembly));
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (assembly.FullName.Contains("Web"))
|
else if (assembly.FullName.Contains("Web"))
|
||||||
{
|
{
|
||||||
_.ApplicationParts.Add(new AssemblyPart(assembly));
|
_partManager.ApplicationParts.Add(new AssemblyPart(assembly));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -58,7 +76,7 @@ namespace WebfrontCore
|
|||||||
});
|
});
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
foreach (var asm in Program.Manager.GetPluginAssemblies())
|
foreach (var asm in pluginAssemblies())
|
||||||
{
|
{
|
||||||
mvcBuilder.AddApplicationPart(asm);
|
mvcBuilder.AddApplicationPart(asm);
|
||||||
}
|
}
|
||||||
@ -83,7 +101,7 @@ namespace WebfrontCore
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
services.AddSingleton(Program.Manager);
|
services.AddSingleton(Program.Manager);
|
||||||
services.AddSingleton(Program.ApplicationServiceProvider.GetService(typeof(IPluginImporter)) as IPluginImporter);
|
services.AddSingleton(Program.ApplicationServiceProvider.GetService<IConfigurationHandlerFactory>());
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user