2022-01-26 11:32:16 -05:00
|
|
|
|
using System;
|
2018-06-30 21:55:16 -04:00
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Text.RegularExpressions;
|
|
|
|
|
using System.Threading.Tasks;
|
2022-01-26 11:32:16 -05:00
|
|
|
|
using SharedLibraryCore.Configuration;
|
|
|
|
|
using SharedLibraryCore.Database.Models;
|
|
|
|
|
using SharedLibraryCore.Exceptions;
|
2018-06-30 21:55:16 -04:00
|
|
|
|
|
|
|
|
|
namespace SharedLibraryCore.Commands
|
|
|
|
|
{
|
|
|
|
|
public class CommandProcessing
|
|
|
|
|
{
|
2022-01-26 11:32:16 -05:00
|
|
|
|
public static async Task<Command> ValidateCommand(GameEvent E, ApplicationConfiguration appConfig,
|
|
|
|
|
CommandConfiguration commandConfig)
|
2018-06-30 21:55:16 -04:00
|
|
|
|
{
|
|
|
|
|
var loc = Utilities.CurrentLocalization.LocalizationIndex;
|
|
|
|
|
var Manager = E.Owner.Manager;
|
2022-01-26 11:32:16 -05:00
|
|
|
|
var isBroadcast = E.Data.StartsWith(appConfig.BroadcastCommandPrefix);
|
|
|
|
|
var prefixLength = isBroadcast ? appConfig.BroadcastCommandPrefix.Length : appConfig.CommandPrefix.Length;
|
2018-06-30 21:55:16 -04:00
|
|
|
|
|
2022-01-26 11:32:16 -05:00
|
|
|
|
var CommandString = E.Data.Substring(prefixLength, E.Data.Length - prefixLength).Split(' ')[0];
|
2018-06-30 21:55:16 -04:00
|
|
|
|
E.Message = E.Data;
|
|
|
|
|
|
|
|
|
|
Command C = null;
|
2021-04-16 14:35:51 -04:00
|
|
|
|
foreach (Command cmd in Manager.GetCommands()
|
2022-01-26 11:32:16 -05:00
|
|
|
|
.Where(c => c.Name != null))
|
|
|
|
|
if (cmd.Name.Equals(CommandString, StringComparison.OrdinalIgnoreCase) ||
|
2020-04-26 22:12:49 -04:00
|
|
|
|
(cmd.Alias ?? "").Equals(CommandString, StringComparison.OrdinalIgnoreCase))
|
2019-03-18 11:36:31 -04:00
|
|
|
|
{
|
2018-06-30 21:55:16 -04:00
|
|
|
|
C = cmd;
|
2019-03-18 11:36:31 -04:00
|
|
|
|
}
|
2018-06-30 21:55:16 -04:00
|
|
|
|
|
|
|
|
|
if (C == null)
|
|
|
|
|
{
|
2018-09-29 15:52:22 -04:00
|
|
|
|
E.Origin.Tell(loc["COMMAND_UNKNOWN"]);
|
2018-06-30 21:55:16 -04:00
|
|
|
|
throw new CommandException($"{E.Origin} entered unknown command \"{CommandString}\"");
|
|
|
|
|
}
|
|
|
|
|
|
2020-07-31 21:40:03 -04:00
|
|
|
|
C.IsBroadcast = isBroadcast;
|
|
|
|
|
|
2021-06-30 19:10:45 -04:00
|
|
|
|
var allowImpersonation = commandConfig?.Commands?.ContainsKey(C.GetType().Name) ?? false
|
|
|
|
|
? commandConfig.Commands[C.GetType().Name].AllowImpersonation
|
|
|
|
|
: C.AllowImpersonation;
|
2022-01-26 11:32:16 -05:00
|
|
|
|
|
2021-06-30 19:10:45 -04:00
|
|
|
|
if (!allowImpersonation && E.ImpersonationOrigin != null)
|
2020-04-26 22:12:49 -04:00
|
|
|
|
{
|
|
|
|
|
E.ImpersonationOrigin.Tell(loc["COMMANDS_RUN_AS_FAIL"]);
|
|
|
|
|
throw new CommandException($"Command {C.Name} cannot be run as another client");
|
|
|
|
|
}
|
|
|
|
|
|
2018-06-30 21:55:16 -04:00
|
|
|
|
E.Data = E.Data.RemoveWords(1);
|
2022-01-26 11:32:16 -05:00
|
|
|
|
var Args = E.Data.Trim().Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
2019-03-18 11:36:31 -04:00
|
|
|
|
// todo: the code below can be cleaned up
|
2018-06-30 21:55:16 -04:00
|
|
|
|
|
|
|
|
|
if (E.Origin.Level < C.Permission)
|
|
|
|
|
{
|
2018-09-29 15:52:22 -04:00
|
|
|
|
E.Origin.Tell(loc["COMMAND_NOACCESS"]);
|
2018-06-30 21:55:16 -04:00
|
|
|
|
throw new CommandException($"{E.Origin} does not have access to \"{C.Name}\"");
|
|
|
|
|
}
|
|
|
|
|
|
2022-01-26 11:32:16 -05:00
|
|
|
|
if (Args.Length < C.RequiredArgumentCount)
|
2018-06-30 21:55:16 -04:00
|
|
|
|
{
|
2018-09-29 15:52:22 -04:00
|
|
|
|
E.Origin.Tell(loc["COMMAND_MISSINGARGS"]);
|
|
|
|
|
E.Origin.Tell(C.Syntax);
|
2018-06-30 21:55:16 -04:00
|
|
|
|
throw new CommandException($"{E.Origin} did not supply enough arguments for \"{C.Name}\"");
|
|
|
|
|
}
|
|
|
|
|
|
2019-03-18 11:36:31 -04:00
|
|
|
|
if (C.RequiresTarget)
|
2018-06-30 21:55:16 -04:00
|
|
|
|
{
|
2019-03-18 11:36:31 -04:00
|
|
|
|
if (Args.Length > 0)
|
2018-06-30 21:55:16 -04:00
|
|
|
|
{
|
2022-01-26 11:32:16 -05:00
|
|
|
|
if (!int.TryParse(Args[0], out var cNum))
|
2019-03-18 11:36:31 -04:00
|
|
|
|
{
|
|
|
|
|
cNum = -1;
|
|
|
|
|
}
|
2018-06-30 21:55:16 -04:00
|
|
|
|
|
2019-03-18 11:36:31 -04:00
|
|
|
|
if (Args[0][0] == '@') // user specifying target by database ID
|
2018-06-30 21:55:16 -04:00
|
|
|
|
{
|
2022-01-26 11:32:16 -05:00
|
|
|
|
int.TryParse(Args[0].Substring(1, Args[0].Length - 1), out var dbID);
|
2019-03-18 11:36:31 -04:00
|
|
|
|
|
|
|
|
|
var found = await Manager.GetClientService().Get(dbID);
|
|
|
|
|
if (found != null)
|
|
|
|
|
{
|
2021-10-31 12:57:32 -04:00
|
|
|
|
found = Manager.FindActiveClient(found);
|
2019-03-18 11:36:31 -04:00
|
|
|
|
E.Target = found;
|
2021-11-03 19:51:52 -04:00
|
|
|
|
E.Target.CurrentServer = found.CurrentServer ?? E.Owner;
|
|
|
|
|
E.Data = string.Join(" ", Args.Skip(1));
|
2019-03-18 11:36:31 -04:00
|
|
|
|
}
|
2018-06-30 21:55:16 -04:00
|
|
|
|
}
|
|
|
|
|
|
2022-01-26 11:32:16 -05:00
|
|
|
|
else if (Args[0].Length < 3 && cNum > -1 && cNum < E.Owner.MaxClients
|
|
|
|
|
) // user specifying target by client num
|
2018-06-30 21:55:16 -04:00
|
|
|
|
{
|
2019-03-18 11:36:31 -04:00
|
|
|
|
if (E.Owner.Clients[cNum] != null)
|
|
|
|
|
{
|
|
|
|
|
E.Target = E.Owner.Clients[cNum];
|
2022-01-26 11:32:16 -05:00
|
|
|
|
E.Data = string.Join(" ", Args.Skip(1));
|
2019-03-18 11:36:31 -04:00
|
|
|
|
}
|
2018-06-30 21:55:16 -04:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-11-05 22:01:29 -05:00
|
|
|
|
List<EFClient> matchingPlayers;
|
2018-06-30 21:55:16 -04:00
|
|
|
|
|
|
|
|
|
if (E.Target == null && C.RequiresTarget) // Find active player including quotes (multiple words)
|
|
|
|
|
{
|
2019-10-11 16:26:13 -04:00
|
|
|
|
matchingPlayers = E.Owner.GetClientByName(E.Data);
|
2018-06-30 21:55:16 -04:00
|
|
|
|
if (matchingPlayers.Count > 1)
|
|
|
|
|
{
|
2018-09-29 15:52:22 -04:00
|
|
|
|
E.Origin.Tell(loc["COMMAND_TARGET_MULTI"]);
|
2018-06-30 21:55:16 -04:00
|
|
|
|
throw new CommandException($"{E.Origin} had multiple players found for {C.Name}");
|
|
|
|
|
}
|
2019-10-11 16:26:13 -04:00
|
|
|
|
|
2022-01-26 11:32:16 -05:00
|
|
|
|
if (matchingPlayers.Count == 1)
|
2018-06-30 21:55:16 -04:00
|
|
|
|
{
|
|
|
|
|
E.Target = matchingPlayers.First();
|
|
|
|
|
|
2022-01-26 11:32:16 -05:00
|
|
|
|
var escapedName = Regex.Escape(E.Target.CleanedName);
|
2018-06-30 21:55:16 -04:00
|
|
|
|
var reg = new Regex($"(\"{escapedName}\")|({escapedName})", RegexOptions.IgnoreCase);
|
|
|
|
|
E.Data = reg.Replace(E.Data, "", 1).Trim();
|
|
|
|
|
|
|
|
|
|
if (E.Data.Length == 0 && C.RequiredArgumentCount > 1)
|
|
|
|
|
{
|
2018-09-29 15:52:22 -04:00
|
|
|
|
E.Origin.Tell(loc["COMMAND_MISSINGARGS"]);
|
|
|
|
|
E.Origin.Tell(C.Syntax);
|
2018-06-30 21:55:16 -04:00
|
|
|
|
throw new CommandException($"{E.Origin} did not supply enough arguments for \"{C.Name}\"");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-03-18 11:36:31 -04:00
|
|
|
|
if (E.Target == null && C.RequiresTarget && Args.Length > 0) // Find active player as single word
|
2018-06-30 21:55:16 -04:00
|
|
|
|
{
|
|
|
|
|
matchingPlayers = E.Owner.GetClientByName(Args[0]);
|
|
|
|
|
if (matchingPlayers.Count > 1)
|
|
|
|
|
{
|
2018-09-29 15:52:22 -04:00
|
|
|
|
E.Origin.Tell(loc["COMMAND_TARGET_MULTI"]);
|
2018-06-30 21:55:16 -04:00
|
|
|
|
foreach (var p in matchingPlayers)
|
2021-11-23 18:26:33 -05:00
|
|
|
|
E.Origin.Tell($"[(Color::Yellow){p.ClientNumber}(Color::White)] {p.Name}");
|
2018-06-30 21:55:16 -04:00
|
|
|
|
throw new CommandException($"{E.Origin} had multiple players found for {C.Name}");
|
|
|
|
|
}
|
2019-03-18 11:36:31 -04:00
|
|
|
|
|
2022-01-26 11:32:16 -05:00
|
|
|
|
if (matchingPlayers.Count == 1)
|
2018-06-30 21:55:16 -04:00
|
|
|
|
{
|
|
|
|
|
E.Target = matchingPlayers.First();
|
|
|
|
|
|
2022-01-26 11:32:16 -05:00
|
|
|
|
var escapedName = Regex.Escape(E.Target.CleanedName);
|
|
|
|
|
var escapedArg = Regex.Escape(Args[0]);
|
2018-06-30 21:55:16 -04:00
|
|
|
|
var reg = new Regex($"({escapedName})|({escapedArg})", RegexOptions.IgnoreCase);
|
|
|
|
|
E.Data = reg.Replace(E.Data, "", 1).Trim();
|
|
|
|
|
|
2019-08-10 10:08:26 -04:00
|
|
|
|
if ((E.Data.Trim() == E.Target.CleanedName.ToLower().Trim() ||
|
2022-01-26 11:32:16 -05:00
|
|
|
|
E.Data == string.Empty) &&
|
2018-06-30 21:55:16 -04:00
|
|
|
|
C.RequiresTarget)
|
|
|
|
|
{
|
2018-09-29 15:52:22 -04:00
|
|
|
|
E.Origin.Tell(loc["COMMAND_MISSINGARGS"]);
|
|
|
|
|
E.Origin.Tell(C.Syntax);
|
2018-06-30 21:55:16 -04:00
|
|
|
|
throw new CommandException($"{E.Origin} did not supply enough arguments for \"{C.Name}\"");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (E.Target == null && C.RequiresTarget)
|
|
|
|
|
{
|
2018-09-29 15:52:22 -04:00
|
|
|
|
E.Origin.Tell(loc["COMMAND_TARGET_NOTFOUND"]);
|
2018-06-30 21:55:16 -04:00
|
|
|
|
throw new CommandException($"{E.Origin} specified invalid player for \"{C.Name}\"");
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-03-18 11:36:31 -04:00
|
|
|
|
|
2018-06-30 21:55:16 -04:00
|
|
|
|
E.Data = E.Data.Trim();
|
|
|
|
|
return C;
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-01-26 11:32:16 -05:00
|
|
|
|
}
|