start work to allow customizing command properties via configuration

This commit is contained in:
RaidMax 2020-01-26 18:06:50 -06:00
parent e6bdcc9012
commit 11ae91281f
16 changed files with 1061 additions and 587 deletions

View File

@ -44,7 +44,7 @@ namespace IW4MAdmin.Application
public string ExternalIPAddress { get; private set; } public string ExternalIPAddress { get; private set; }
public bool IsRestartRequested { get; private set; } public bool IsRestartRequested { get; private set; }
public IMiddlewareActionHandler MiddlewareActionHandler { get; } public IMiddlewareActionHandler MiddlewareActionHandler { get; }
private readonly List<Command> Commands; private readonly List<IManagerCommand> _commands;
private readonly List<MessageToken> MessageTokens; private readonly List<MessageToken> MessageTokens;
private readonly ClientService ClientSvc; private readonly ClientService ClientSvc;
readonly AliasService AliasSvc; readonly AliasService AliasSvc;
@ -57,12 +57,13 @@ namespace IW4MAdmin.Application
private readonly TimeSpan _throttleTimeout = new TimeSpan(0, 1, 0); private readonly TimeSpan _throttleTimeout = new TimeSpan(0, 1, 0);
private readonly CancellationTokenSource _tokenSource; private readonly CancellationTokenSource _tokenSource;
private readonly Dictionary<string, Task<IList>> _operationLookup = new Dictionary<string, Task<IList>>(); private readonly Dictionary<string, Task<IList>> _operationLookup = new Dictionary<string, Task<IList>>();
private readonly ITranslationLookup _translationLookup;
private readonly CommandConfiguration _commandConfiguration;
public ApplicationManager(ILogger logger, IMiddlewareActionHandler actionHandler) public ApplicationManager(ILogger logger, IMiddlewareActionHandler actionHandler, IEnumerable<IManagerCommand> commands, ITranslationLookup translationLookup, CommandConfiguration commandConfiguration)
{ {
MiddlewareActionHandler = actionHandler; MiddlewareActionHandler = actionHandler;
_servers = new ConcurrentBag<Server>(); _servers = new ConcurrentBag<Server>();
Commands = new List<Command>();
MessageTokens = new List<MessageToken>(); MessageTokens = new List<MessageToken>();
ClientSvc = new ClientService(); ClientSvc = new ClientService();
AliasSvc = new AliasService(); AliasSvc = new AliasService();
@ -76,6 +77,9 @@ namespace IW4MAdmin.Application
_metaService = new MetaService(); _metaService = new MetaService();
_tokenSource = new CancellationTokenSource(); _tokenSource = new CancellationTokenSource();
_loggers.Add(0, logger); _loggers.Add(0, logger);
_commands = commands.ToList();
_translationLookup = translationLookup;
_commandConfiguration = commandConfiguration;
} }
public async Task ExecuteEvent(GameEvent newEvent) public async Task ExecuteEvent(GameEvent newEvent)
@ -155,7 +159,7 @@ namespace IW4MAdmin.Application
public IList<Command> GetCommands() public IList<Command> GetCommands()
{ {
return Commands; return new List<Command>();
} }
public async Task UpdateServerStates() public async Task UpdateServerStates()
@ -293,7 +297,7 @@ namespace IW4MAdmin.Application
serverConfig.AddEventParser(parser); serverConfig.AddEventParser(parser);
} }
newConfig.Servers[0] = (ServerConfiguration)serverConfig.Generate(); newConfig.Servers = newConfig.Servers.Append((ServerConfiguration)serverConfig.Generate()).ToArray();
} while (Utilities.PromptBool(Utilities.CurrentLocalization.LocalizationIndex["SETUP_SERVER_SAVE"])); } while (Utilities.PromptBool(Utilities.CurrentLocalization.LocalizationIndex["SETUP_SERVER_SAVE"]));
config = newConfig; config = newConfig;
@ -367,55 +371,35 @@ namespace IW4MAdmin.Application
#endregion #endregion
#region COMMANDS #region COMMANDS
if (ClientSvc.GetOwners().Result.Count == 0) if (ClientSvc.GetOwners().Result.Count > 0)
{ {
Commands.Add(new COwner()); _commands.RemoveAll(_cmd => _cmd.GetType() == typeof(OwnerCommand));
} }
Commands.Add(new CQuit());
Commands.Add(new CRestart());
Commands.Add(new CKick());
Commands.Add(new CSay());
Commands.Add(new CTempBan());
Commands.Add(new CBan());
Commands.Add(new CWhoAmI());
Commands.Add(new CList());
Commands.Add(new CHelp());
Commands.Add(new CFastRestart());
Commands.Add(new CMapRotate());
Commands.Add(new CSetLevel());
Commands.Add(new CUsage());
Commands.Add(new CUptime());
Commands.Add(new CWarn());
Commands.Add(new CWarnClear());
Commands.Add(new CUnban());
Commands.Add(new CListAdmins());
Commands.Add(new CLoadMap());
Commands.Add(new CFindPlayer());
Commands.Add(new CListRules());
Commands.Add(new CPrivateMessage());
Commands.Add(new CFlag());
Commands.Add(new CUnflag());
Commands.Add(new CReport());
Commands.Add(new CListReports());
Commands.Add(new CListBanInfo());
Commands.Add(new CListAlias());
Commands.Add(new CExecuteRCON());
Commands.Add(new CPlugins());
Commands.Add(new CIP());
Commands.Add(new CMask());
Commands.Add(new CPruneAdmins());
//Commands.Add(new CKillServer());
Commands.Add(new CSetPassword());
Commands.Add(new CPing());
Commands.Add(new CSetGravatar());
Commands.Add(new CNextMap());
Commands.Add(new RequestTokenCommand());
Commands.Add(new UnlinkClientCommand());
foreach (Command C in SharedLibraryCore.Plugins.PluginImporter.ActiveCommands) foreach (Command C in SharedLibraryCore.Plugins.PluginImporter.ActiveCommands)
{ {
Commands.Add(C); _commands.Add(C);
}
if (_commandConfiguration == null)
{
// todo: this is here for now. it's not the most elegant but currently there's no way to know all the plugin comamnds during DI
var handler = new BaseConfigurationHandler<CommandConfiguration>("CommandConfiguration");
var cmdConfig = new CommandConfiguration();
foreach (var cmd in _commands)
{
cmdConfig.Commands.Add(cmd.GetType().Name,
new CommandProperties()
{
Name = cmd.Name,
Alias = cmd.Alias,
MinimumPermission = cmd.Permission
});
}
handler.Set(cmdConfig);
await handler.Save();
} }
#endregion #endregion
@ -557,7 +541,7 @@ namespace IW4MAdmin.Application
try try
{ {
var ServerInstance = new IW4MServer(this, Conf); var ServerInstance = new IW4MServer(this, Conf, _translationLookup);
await ServerInstance.Initialize(); await ServerInstance.Initialize();
_servers.Add(ServerInstance); _servers.Add(ServerInstance);

View File

@ -23,14 +23,16 @@ namespace IW4MAdmin
{ {
public class IW4MServer : Server public class IW4MServer : Server
{ {
private static readonly SharedLibraryCore.Localization.Index loc = Utilities.CurrentLocalization.LocalizationIndex; private static readonly SharedLibraryCore.Localization.TranslationLookup loc = Utilities.CurrentLocalization.LocalizationIndex;
private GameLogEventDetection LogEvent; private GameLogEventDetection LogEvent;
private readonly ITranslationLookup _translationLookup;
private const int REPORT_FLAG_COUNT = 4; private const int REPORT_FLAG_COUNT = 4;
public int Id { get; private set; } public int Id { get; private set; }
public IW4MServer(IManager mgr, ServerConfiguration cfg) : base(mgr, cfg) public IW4MServer(IManager mgr, ServerConfiguration cfg, ITranslationLookup lookup) : base(mgr, cfg)
{ {
_translationLookup = lookup;
} }
override public async Task<EFClient> OnClientConnected(EFClient clientFromLog) override public async Task<EFClient> OnClientConnected(EFClient clientFromLog)
@ -1186,8 +1188,8 @@ namespace IW4MAdmin
{ {
Manager.GetMessageTokens().Add(new MessageToken("TOTALPLAYERS", (Server s) => Task.Run(async () => (await Manager.GetClientService().GetTotalClientsAsync()).ToString()))); Manager.GetMessageTokens().Add(new MessageToken("TOTALPLAYERS", (Server s) => Task.Run(async () => (await Manager.GetClientService().GetTotalClientsAsync()).ToString())));
Manager.GetMessageTokens().Add(new MessageToken("VERSION", (Server s) => Task.FromResult(Application.Program.Version.ToString()))); Manager.GetMessageTokens().Add(new MessageToken("VERSION", (Server s) => Task.FromResult(Application.Program.Version.ToString())));
Manager.GetMessageTokens().Add(new MessageToken("NEXTMAP", (Server s) => SharedLibraryCore.Commands.CNextMap.GetNextMap(s))); Manager.GetMessageTokens().Add(new MessageToken("NEXTMAP", (Server s) => SharedLibraryCore.Commands.NextMapCommand.GetNextMap(s, _translationLookup)));
Manager.GetMessageTokens().Add(new MessageToken("ADMINS", (Server s) => Task.FromResult(SharedLibraryCore.Commands.CListAdmins.OnlineAdmins(s)))); Manager.GetMessageTokens().Add(new MessageToken("ADMINS", (Server s) => Task.FromResult(SharedLibraryCore.Commands.ListAdminsCommand.OnlineAdmins(s, _translationLookup))));
} }
} }
} }

View File

@ -1,30 +1,29 @@
using IW4MAdmin.Application.API.Master; using IW4MAdmin.Application.API.Master;
using SharedLibraryCore; using SharedLibraryCore;
using SharedLibraryCore.Interfaces;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.IO; using System.IO;
using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks;
namespace IW4MAdmin.Application.Localization namespace IW4MAdmin.Application.Localization
{ {
public class Configure public class Configure
{ {
public static void Initialize(string customLocale = null) public static ITranslationLookup Initialize(bool useLocalTranslation, string customLocale = null)
{ {
string currentLocale = string.IsNullOrEmpty(customLocale) ? CultureInfo.CurrentCulture.Name : customLocale; string currentLocale = string.IsNullOrEmpty(customLocale) ? CultureInfo.CurrentCulture.Name : customLocale;
string[] localizationFiles = Directory.GetFiles(Path.Join(Utilities.OperatingDirectory, "Localization"), $"*.{currentLocale}.json"); string[] localizationFiles = Directory.GetFiles(Path.Join(Utilities.OperatingDirectory, "Localization"), $"*.{currentLocale}.json");
if (!Program.ServerManager.GetApplicationSettings()?.Configuration()?.UseLocalTranslations ?? false) if (!useLocalTranslation)
{ {
try try
{ {
var api = Endpoint.Get(); var api = Endpoint.Get();
var localization = api.GetLocalization(currentLocale).Result; var localization = api.GetLocalization(currentLocale).Result;
Utilities.CurrentLocalization = localization; Utilities.CurrentLocalization = localization;
return; return localization.LocalizationIndex;
} }
catch (Exception) catch (Exception)
@ -73,6 +72,8 @@ namespace IW4MAdmin.Application.Localization
{ {
LocalizationName = currentLocale, LocalizationName = currentLocale,
}; };
return Utilities.CurrentLocalization.LocalizationIndex;
} }
} }
} }

View File

@ -2,10 +2,12 @@
using IW4MAdmin.Application.Misc; using IW4MAdmin.Application.Misc;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using SharedLibraryCore; using SharedLibraryCore;
using SharedLibraryCore.Configuration;
using SharedLibraryCore.Exceptions; using SharedLibraryCore.Exceptions;
using SharedLibraryCore.Helpers; using SharedLibraryCore.Helpers;
using SharedLibraryCore.Interfaces; using SharedLibraryCore.Interfaces;
using System; using System;
using System.Linq;
using System.Text; using System.Text;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -69,9 +71,6 @@ namespace IW4MAdmin.Application
ServerManager = (ApplicationManager)builder.GetRequiredService<IManager>(); ServerManager = (ApplicationManager)builder.GetRequiredService<IManager>();
} }
var configuration = ServerManager.GetApplicationSettings().Configuration();
Localization.Configure.Initialize(configuration?.EnableCustomLocale ?? false ? (configuration.CustomLocale ?? "en-US") : "en-US");
// do any needed housekeeping file/folder migrations // do any needed housekeeping file/folder migrations
ConfigurationMigration.MoveConfigFolder10518(null); ConfigurationMigration.MoveConfigFolder10518(null);
ConfigurationMigration.CheckDirectories(); ConfigurationMigration.CheckDirectories();
@ -259,8 +258,21 @@ namespace IW4MAdmin.Application
{ {
var serviceProvider = new ServiceCollection(); var serviceProvider = new ServiceCollection();
serviceProvider.AddSingleton<IManager, ApplicationManager>() serviceProvider.AddSingleton<IManager, ApplicationManager>()
.AddSingleton(_serviceProvider => new BaseConfigurationHandler<ApplicationConfiguration>("IW4MAdminSettings").Configuration())
.AddSingleton(_serviceProvider => new BaseConfigurationHandler<CommandConfiguration>("CommandConfiguration").Configuration())
.AddSingleton<ILogger>(_serviceProvider => new Logger("IW4MAdmin-Manager")) .AddSingleton<ILogger>(_serviceProvider => new Logger("IW4MAdmin-Manager"))
.AddSingleton<IMiddlewareActionHandler, MiddlewareActionHandler>(); .AddSingleton<IMiddlewareActionHandler, MiddlewareActionHandler>()
.AddSingleton(_serviceProvider =>
{
var config = _serviceProvider.GetRequiredService<ApplicationConfiguration>();
return Localization.Configure.Initialize(config?.UseLocalTranslations ?? false, config?.EnableCustomLocale ?? false ? (config.CustomLocale ?? "en-US") : "en-US");
});
foreach (var commandDefinition in typeof(SharedLibraryCore.Commands.QuitCommand).Assembly.GetTypes().Where(_command => _command.BaseType == typeof(Command)))
{
serviceProvider.AddTransient(typeof(IManagerCommand), commandDefinition);
}
return serviceProvider; return serviceProvider;
} }

View File

@ -293,7 +293,7 @@ namespace Tests
var client = _manager.Servers.First().GetClientsAsList().FirstOrDefault(); var client = _manager.Servers.First().GetClientsAsList().FirstOrDefault();
Assert.False(client == null, "no client found to tempban"); Assert.False(client == null, "no client found to tempban");
var tbCommand = new CTempBan(); /* var tbCommand = new TempBanCommand();
tbCommand.ExecuteAsync(new GameEvent() tbCommand.ExecuteAsync(new GameEvent()
{ {
Origin = new EFClient() { ClientId = 1, Level = EFClient.Permission.Console, CurrentServer = client.CurrentServer }, Origin = new EFClient() { ClientId = 1, Level = EFClient.Permission.Console, CurrentServer = client.CurrentServer },
@ -304,7 +304,7 @@ namespace Tests
}).Wait(); }).Wait();
Assert.True(_manager.GetPenaltyService().GetActivePenaltiesAsync(client.AliasLinkId).Result.Count(p => p.Type == EFPenalty.PenaltyType.TempBan) == 1, Assert.True(_manager.GetPenaltyService().GetActivePenaltiesAsync(client.AliasLinkId).Result.Count(p => p.Type == EFPenalty.PenaltyType.TempBan) == 1,
"tempban was not added"); "tempban was not added");*/
} }
[Fact] [Fact]
@ -317,8 +317,8 @@ namespace Tests
var client = _manager.Servers.First().GetClientsAsList().FirstOrDefault(); var client = _manager.Servers.First().GetClientsAsList().FirstOrDefault();
Assert.False(client == null, "no client found to ban"); Assert.False(client == null, "no client found to ban");
/*
var banCommand = new CBan(); var banCommand = new BanCommand();
banCommand.ExecuteAsync(new GameEvent() banCommand.ExecuteAsync(new GameEvent()
{ {
Origin = new EFClient() { ClientId = 1, Level = EFClient.Permission.Console, CurrentServer = client.CurrentServer }, Origin = new EFClient() { ClientId = 1, Level = EFClient.Permission.Console, CurrentServer = client.CurrentServer },
@ -331,7 +331,7 @@ namespace Tests
Assert.True(_manager.GetPenaltyService().GetActivePenaltiesAsync(client.AliasLinkId).Result.Count(p => p.Type == EFPenalty.PenaltyType.Ban) == 1, Assert.True(_manager.GetPenaltyService().GetActivePenaltiesAsync(client.AliasLinkId).Result.Count(p => p.Type == EFPenalty.PenaltyType.Ban) == 1,
"ban was not added"); "ban was not added");
var unbanCommand = new CUnban(); var unbanCommand = new UnbanCommand();
unbanCommand.ExecuteAsync(new GameEvent() unbanCommand.ExecuteAsync(new GameEvent()
{ {
Origin = new EFClient() { ClientId = 1, Level = EFClient.Permission.Console, CurrentServer = client.CurrentServer }, Origin = new EFClient() { ClientId = 1, Level = EFClient.Permission.Console, CurrentServer = client.CurrentServer },
@ -342,7 +342,7 @@ namespace Tests
}).Wait(); }).Wait();
Assert.True(_manager.GetPenaltyService().GetActivePenaltiesAsync(client.AliasLinkId).Result.Count(p => p.Type == EFPenalty.PenaltyType.Ban) == 0, Assert.True(_manager.GetPenaltyService().GetActivePenaltiesAsync(client.AliasLinkId).Result.Count(p => p.Type == EFPenalty.PenaltyType.Ban) == 0,
"ban was not removed"); "ban was not removed");*/
} }
} }

View File

@ -25,7 +25,7 @@ namespace SharedLibraryCore
public IManager Manager { get; private set; } public IManager Manager { get; private set; }
protected readonly DatabaseContext Context; protected readonly DatabaseContext Context;
protected bool Authorized { get; set; } protected bool Authorized { get; set; }
protected SharedLibraryCore.Localization.Index Localization { get; private set; } protected SharedLibraryCore.Localization.TranslationLookup Localization { get; private set; }
protected EFClient Client { get; private set; } protected EFClient Client { get; private set; }
private static readonly byte[] LocalHost = { 127, 0, 0, 1 }; private static readonly byte[] LocalHost = { 127, 0, 0, 1 };
private static string SocialLink; private static string SocialLink;

View File

@ -1,38 +1,121 @@
using System; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using SharedLibraryCore.Commands;
using SharedLibraryCore.Configuration;
using SharedLibraryCore.Database.Models; using SharedLibraryCore.Database.Models;
using SharedLibraryCore.Interfaces;
namespace SharedLibraryCore namespace SharedLibraryCore
{ {
public class CommandArgument /// <summary>
/// Abstract class for command
/// </summary>
public abstract class Command : IManagerCommand
{ {
public string Name { get; set; } private readonly CommandConfiguration _config;
public bool Required { get; set; } protected readonly ITranslationLookup _translationLookup;
}
public abstract class Command public Command(CommandConfiguration config, ITranslationLookup layout)
{ {
public Command(String commandName, String commandDescription, String commandAlias, EFClient.Permission requiredPermission, bool requiresTarget, CommandArgument[] param = null) _config = config;
{ _translationLookup = layout;
Name = commandName;
Description = commandDescription;
Alias = commandAlias;
Permission = requiredPermission;
RequiresTarget = requiresTarget;
Arguments = param ?? new CommandArgument[0];
} }
//Execute the command /// <summary>
/// Executes the command
/// </summary>
/// <param name="E"></param>
/// <returns></returns>
abstract public Task ExecuteAsync(GameEvent E); abstract public Task ExecuteAsync(GameEvent E);
public String Name { get; private set; } /// <summary>
public String Description { get; private set; } /// Specifies the name and string that triggers the command
public String Syntax => $"{Utilities.CurrentLocalization.LocalizationIndex["COMMAND_HELP_SYNTAX"]} !{Alias} {String.Join(" ", Arguments.Select(a => $"<{(a.Required ? "" : Utilities.CurrentLocalization.LocalizationIndex["COMMAND_HELP_OPTIONAL"] + " ")}{a.Name}>"))}"; /// </summary>
public String Alias { get; private set; } public string Name
{
get => name;
protected set
{
try
{
name = _config?.Commands[GetType().Name].Name ?? value;
}
catch (KeyNotFoundException)
{
name = value;
}
}
}
private string name;
/// <summary>
/// Specifies the command description
/// </summary>
public string Description { get; protected set; }
/// <summary>
/// Helper property to provide the syntax of the command
/// </summary>
public string Syntax => $"{_translationLookup["COMMAND_HELP_SYNTAX"]} !{Alias} {string.Join(" ", Arguments.Select(a => $"<{(a.Required ? "" : _translationLookup["COMMAND_HELP_OPTIONAL"] + " ")}{a.Name}>"))}";
/// <summary>
/// Alternate name for this command to be executed by
/// </summary>
public string Alias
{
get => alias;
protected set
{
try
{
alias = _config?.Commands[GetType().Name].Alias ?? value;
}
catch (KeyNotFoundException)
{
alias = value;
}
}
}
private string alias;
/// <summary>
/// Helper property to determine the number of required args
/// </summary>
public int RequiredArgumentCount => Arguments.Count(c => c.Required); public int RequiredArgumentCount => Arguments.Count(c => c.Required);
public bool RequiresTarget { get; private set; }
public EFClient.Permission Permission { get; private set; } /// <summary>
public CommandArgument[] Arguments { get; private set; } /// Indicates if the command requires a target to execute on
/// </summary>
public bool RequiresTarget { get; protected set; }
/// <summary>
/// Minimum permission level to execute command
/// </summary>
public EFClient.Permission Permission
{
get => permission;
protected set
{
try
{
permission = _config?.Commands[GetType().Name].MinimumPermission ?? value;
}
catch (KeyNotFoundException)
{
permission = value;
}
}
}
private EFClient.Permission permission;
/// <summary>
/// Argument list for the command
/// </summary>
public CommandArgument[] Arguments { get; protected set; } = new CommandArgument[0];
} }
} }

View File

@ -0,0 +1,18 @@
namespace SharedLibraryCore.Commands
{
/// <summary>
/// Holds information about command args
/// </summary>
public class CommandArgument
{
/// <summary>
/// Name of the argument
/// </summary>
public string Name { get; set; }
/// <summary>
/// Indicates if the argument is required
/// </summary>
public bool Required { get; set; }
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,18 +1,28 @@
using SharedLibraryCore.Database.Models; using SharedLibraryCore.Configuration;
using SharedLibraryCore.Database.Models;
using SharedLibraryCore.Interfaces;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace SharedLibraryCore.Commands namespace SharedLibraryCore.Commands
{ {
/// <summary>
/// Generates a token for use in webfront login
/// </summary>
public class RequestTokenCommand : Command public class RequestTokenCommand : Command
{ {
public RequestTokenCommand() : public RequestTokenCommand(CommandConfiguration config, ITranslationLookup lookup) : base(config, lookup)
base("requesttoken", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_GENERATETOKEN_DESC"], "rt", EFClient.Permission.Trusted, false) {
{ } Name = "requesttoken";
Description = lookup["COMMANDS_GENERATETOKEN_DESC"];
Alias = "rt";
Permission = EFClient.Permission.Trusted;
RequiresTarget = false;
}
public override Task ExecuteAsync(GameEvent E) public override Task ExecuteAsync(GameEvent E)
{ {
var state = E.Owner.Manager.TokenAuthenticator.GenerateNextToken(E.Origin.NetworkId); var state = E.Owner.Manager.TokenAuthenticator.GenerateNextToken(E.Origin.NetworkId);
E.Origin.Tell(string.Format(Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_GENERATETOKEN_SUCCESS"], state.Token, $"{state.RemainingTime} {Utilities.CurrentLocalization.LocalizationIndex["GLOBAL_MINUTES"]}", E.Origin.ClientId)); E.Origin.Tell(string.Format(_translationLookup["COMMANDS_GENERATETOKEN_SUCCESS"], state.Token, $"{state.RemainingTime} {_translationLookup["GLOBAL_MINUTES"]}", E.Origin.ClientId));
return Task.CompletedTask; return Task.CompletedTask;
} }

View File

@ -1,4 +1,6 @@
using SharedLibraryCore.Database.Models; using SharedLibraryCore.Configuration;
using SharedLibraryCore.Database.Models;
using SharedLibraryCore.Interfaces;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace SharedLibraryCore.Commands namespace SharedLibraryCore.Commands
@ -12,14 +14,19 @@ namespace SharedLibraryCore.Commands
/// </summary> /// </summary>
public class UnlinkClientCommand : Command public class UnlinkClientCommand : Command
{ {
public UnlinkClientCommand() : public UnlinkClientCommand(CommandConfiguration config, ITranslationLookup lookup) : base(config, lookup)
base("unlinkclient", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_UNLINK_CLIENT_DESC"], "uc", EFClient.Permission.Administrator, true) {
{ } Name = "unlinkclient";
Description = lookup["COMMANDS_UNLINK_CLIENT_DESC"];
Alias = "uc";
Permission = EFClient.Permission.Administrator;
RequiresTarget = true;
}
public override async Task ExecuteAsync(GameEvent E) public override async Task ExecuteAsync(GameEvent E)
{ {
await E.Owner.Manager.GetClientService().UnlinkClient(E.Target.ClientId); await E.Owner.Manager.GetClientService().UnlinkClient(E.Target.ClientId);
E.Origin.Tell(Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_UNLINK_CLIENT_SUCCESS"].FormatExt(E.Target)); E.Origin.Tell(_translationLookup["COMMANDS_UNLINK_CLIENT_SUCCESS"].FormatExt(E.Target));
} }
} }
} }

View File

@ -0,0 +1,24 @@
using SharedLibraryCore.Interfaces;
using System;
using System.Collections.Generic;
namespace SharedLibraryCore.Configuration
{
/// <summary>
/// Basic command configuration
/// </summary>
public class CommandConfiguration : IBaseConfiguration
{
/// <summary>
/// Dict of command class names mapped to configurable properties
/// </summary>
public Dictionary<string, CommandProperties> Commands { get; set; } = new Dictionary<string, CommandProperties>();
public IBaseConfiguration Generate()
{
throw new NotImplementedException();
}
public string Name() => nameof(CommandConfiguration);
}
}

View File

@ -0,0 +1,28 @@
using Newtonsoft.Json.Converters;
using System.Text.Json.Serialization;
using static SharedLibraryCore.Database.Models.EFClient;
namespace SharedLibraryCore.Configuration
{
/// <summary>
/// Config driven command properties
/// </summary>
public class CommandProperties
{
/// <summary>
/// Specifies the command name
/// </summary>
public string Name { get; set; }
/// <summary>
/// Alias of this command
/// </summary>
public string Alias { get; set; }
/// <summary>
/// Specifies the minimum permission level needed to execute the
/// </summary>
[JsonConverter(typeof(StringEnumConverter))]
public Permission MinimumPermission { get; set; }
}
}

View File

@ -0,0 +1,38 @@
using System.Threading.Tasks;
using static SharedLibraryCore.Database.Models.EFClient;
namespace SharedLibraryCore.Interfaces
{
/// <summary>
/// Defines the basic properties of a command
/// </summary>
public interface IManagerCommand
{
/// <summary>
/// Executes the command
/// </summary>
/// <param name="gameEvent">event corresponding to the command</param>
/// <returns></returns>
Task ExecuteAsync(GameEvent gameEvent);
/// <summary>
/// Name of the command
/// </summary>
string Name { get; }
/// <summary>
/// Description of the command
/// </summary>
string Description { get; }
/// <summary>
/// Alternative name of the command
/// </summary>
string Alias { get; }
/// <summary>
/// Minimum permission required to execute the command
/// </summary>
Permission Permission { get; }
}
}

View File

@ -0,0 +1,15 @@
namespace SharedLibraryCore.Interfaces
{
/// <summary>
/// Defines the translation lookup capabilities for DI
/// </summary>
public interface ITranslationLookup
{
/// <summary>
/// Allows indexing
/// </summary>
/// <param name="key">translation lookup key</param>
/// <returns></returns>
string this[string key] { get; }
}
}

View File

@ -1,25 +1,23 @@
using Newtonsoft.Json; using SharedLibraryCore.Interfaces;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text;
namespace SharedLibraryCore.Localization namespace SharedLibraryCore.Localization
{ {
public class Layout public class Layout
{ {
public string LocalizationName { get; set; } public string LocalizationName { get; set; }
public Index LocalizationIndex { get; set; } public TranslationLookup LocalizationIndex { get; set; }
public Layout(Dictionary<string, string> set) public Layout(Dictionary<string, string> set)
{ {
LocalizationIndex = new Index() LocalizationIndex = new TranslationLookup()
{ {
Set = set Set = set
}; };
} }
} }
public class Index public class TranslationLookup : ITranslationLookup
{ {
public Dictionary<string, string> Set { get; set; } public Dictionary<string, string> Set { get; set; }