implement basic run-as functionality
This commit is contained in:
RaidMax
2020-04-26 21:12:49 -05:00
parent 3645cf53ff
commit 58bfd189d0
20 changed files with 1294 additions and 18 deletions

View File

@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace SharedLibraryCore.Commands
{
public static class CommandExtensions
{
public static bool IsTargetingSelf(this GameEvent gameEvent) => gameEvent.Origin?.Equals(gameEvent.Target) ?? false;
public static bool CanPerformActionOnTarget(this GameEvent gameEvent) => gameEvent.Origin?.Level > gameEvent.Target?.Level;
}
}

View File

@ -21,7 +21,8 @@ namespace SharedLibraryCore.Commands
Command C = null;
foreach (Command cmd in Manager.GetCommands())
{
if (cmd.Name == CommandString.ToLower() || cmd.Alias == CommandString.ToLower())
if (cmd.Name.Equals(CommandString, StringComparison.OrdinalIgnoreCase) ||
(cmd.Alias ?? "").Equals(CommandString, StringComparison.OrdinalIgnoreCase))
{
C = cmd;
}
@ -33,6 +34,12 @@ namespace SharedLibraryCore.Commands
throw new CommandException($"{E.Origin} entered unknown command \"{CommandString}\"");
}
if (!C.AllowImpersonation && E.ImpersonationOrigin != null)
{
E.ImpersonationOrigin.Tell(loc["COMMANDS_RUN_AS_FAIL"]);
throw new CommandException($"Command {C.Name} cannot be run as another client");
}
E.Data = E.Data.RemoveWords(1);
String[] Args = E.Data.Trim().Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
// todo: the code below can be cleaned up

View File

@ -1434,6 +1434,7 @@ namespace SharedLibraryCore.Commands
Alias = "sp";
Permission = Permission.Moderator;
RequiresTarget = false;
AllowImpersonation = true;
Arguments = new[]
{
new CommandArgument()

View File

@ -0,0 +1,65 @@
using SharedLibraryCore.Configuration;
using SharedLibraryCore.Database.Models;
using SharedLibraryCore.Interfaces;
using System.Linq;
using System.Threading.Tasks;
namespace SharedLibraryCore.Commands
{
public class RunAsCommand : Command
{
public RunAsCommand(CommandConfiguration config, ITranslationLookup lookup) : base(config, lookup)
{
Name = "runas";
Description = lookup["COMMANDS_RUN_AS_DESC"];
Alias = "ra";
Permission = EFClient.Permission.Moderator;
RequiresTarget = true;
Arguments = new[]
{
new CommandArgument()
{
Name = lookup["COMMANDS_ARGS_COMMANDS"],
Required = true
}
};
}
public override async Task ExecuteAsync(GameEvent E)
{
if (E.IsTargetingSelf())
{
E.Origin.Tell(_translationLookup["COMMANDS_RUN_AS_SELF"]);
return;
}
if (!E.CanPerformActionOnTarget())
{
E.Origin.Tell(_translationLookup["COMMANDS_RUN_AS_FAIL_PERM"]);
return;
}
string cmd = $"{Utilities.CommandPrefix}{E.Data}";
var impersonatedCommandEvent = new GameEvent()
{
Type = GameEvent.EventType.Command,
Origin = E.Target,
ImpersonationOrigin = E.Origin,
Message = cmd,
Data = cmd,
Owner = E.Owner
};
E.Owner.Manager.GetEventHandler().AddEvent(impersonatedCommandEvent);
var result = await impersonatedCommandEvent.WaitAsync(Utilities.DefaultCommandTimeout, E.Owner.Manager.CancellationToken);
var response = E.Owner.CommandResult.Where(c => c.ClientId == E.Target.ClientId).ToList();
// remove the added command response
for (int i = 0; i < response.Count; i++)
{
E.Origin.Tell(_translationLookup["COMMANDS_RUN_AS_SUCCESS"].FormatExt(response[i].Response));
E.Owner.CommandResult.Remove(response[i]);
}
}
}
}