예제 #1
0
        protected virtual void OnPrivmsg(string source, string target, string message)
        {
            PrivmsgReceivedEvent.Raise(this, new MessageReceivedEventArgs(source, target, message));

            // TODO: Support non-channel commands (ie: PM commands)
            // TODO: Support non-standard channels (ie: use CHANTYPES from 005).
            if (EnableCommandParsing && target[0].Equals('#') && message.Length > 1 && message[0] == CommandPrefix)
            {
                string[] toks       = message.Split(' ');
                string   command    = toks[0].Substring(1);
                string[] parameters = toks.Skip(1).ToArray();

                char access = '\0';
                var  c      = GetChannel(target);
                if (c != null)
                {
                    string     nick = source.GetNickFromSource();
                    PrefixList l;
                    if (c.Users.TryGetValue(nick, out l))
                    {
                        access = l.HighestPrefix;
                    }
                }

                CanExecuteCommandEventArgs args = new CanExecuteCommandEventArgs(command, source, access, parameters);
                CanExecuteCommandEvent.Raise(this, args);

                if (args.CanExecute)
                {
                    CommandExecutedEvent.Raise(this, new CommandExecuteEventArgs(command, source, access, parameters));
                }
            }
        }
 public async Task HandleEventAsync(object sender, CommandExecutedEvent @event)
 {
     if (@event.CommandContext.Exception == null || @event.ExceptionHandled)
     {
         // Command was successfully executed
         await m_CooldownManager.RecordExecution(@event.Actor, @event.CommandContext.CommandRegistration.Id, DateTime.Now);
     }
 }
예제 #3
0
        private async Task <bool> CheckCooldownAsync(CommandExecutedEvent @event)
        {
            const string rocketPrefix = "rocket:";

            var commandContext = @event.CommandContext;
            var commandAlias   = commandContext.CommandAlias;

            if (string.IsNullOrEmpty(commandAlias))
            {
                return(true);
            }

            if (@event.Actor is not UnturnedUser user)
            {
                return(true);
            }

            if (commandAlias.StartsWith(rocketPrefix))
            {
                commandAlias = commandAlias.Replace(rocketPrefix, string.Empty);
            }

            var steamPlayer  = user.Player.SteamPlayer;
            var rocketPlayer = UnturnedPlayer.FromSteamPlayer(steamPlayer);
            var command      = R.Commands.GetCommand(commandAlias.ToLower());

            if (command == null || !R.Permissions.HasPermission(rocketPlayer, command))
            {
                return(true);
            }

            var commandId    = string.Format(RocketCooldownsFormat, command.Name);
            var cooldownSpan = await m_CommandCooldownStore.GetCooldownSpanAsync(commandContext.Actor, commandId);

            if (cooldownSpan.HasValue)
            {
                var lastExecuted = await m_CommandCooldownStore.GetLastExecutedAsync(@event.Actor, commandId);

                if (lastExecuted.HasValue)
                {
                    var spanSinceLast = DateTime.Now - lastExecuted.Value;

                    if (spanSinceLast < cooldownSpan)
                    {
                        @event.CommandContext.Exception = new UserFriendlyException(
                            m_StringLocalizer["commands:errors:cooldown",
                                              new { TimeLeft = cooldownSpan - spanSinceLast }]);

                        @event.ExceptionHandled = false;
                        return(false);
                    }
                }

                await m_CommandCooldownStore.RecordExecutionAsync(commandContext.Actor, commandId, DateTime.Now);
            }

            return(true);
        }
예제 #4
0
        public void Handle(CommandExecutedEvent message)
        {
            var scheduledTask = _scheduledTaskRepository.All().SingleOrDefault(c => c.TypeName == message.Command.Body.GetType().FullName);

            if (scheduledTask != null && message.Command.Body.UpdateScheduledTask)
            {
                _logger.Trace("Updating last run time for: {0}", scheduledTask.TypeName);
                _scheduledTaskRepository.SetLastExecutionTime(scheduledTask.Id, DateTime.UtcNow);
            }
        }
예제 #5
0
        private void OnCommandExecuted(CommandExecutedEvent eventdata)
        {
            eventdata.Cancelled = true;
            var commandResult = eventdata.Result;

            switch (commandResult.Status)
            {
            case CommandExecutionStatus.Ok:
                // Do nothing
                break;

            case CommandExecutionStatus.Exception:
                eventdata.Player.SendMessage(Color.LightGray, "An error occured during command execution. Try again later.");

                break;

            case CommandExecutionStatus.NoPermission:
                eventdata.Player.SendMessage(Color.LightGray, "You don't have the needed permissions to execute this command.");

                break;

            case CommandExecutionStatus.ArgumentTypeMismatch when eventdata.Command != null:
                eventdata.Player.SendMessage(Color.LightGray, string.Empty);
                eventdata.Player.SendMessage(Color.LightGray, $"Could not match input to expected types. {(string.IsNullOrWhiteSpace(eventdata.ErrorParameter) == false ? $"Parameter: {eventdata.ErrorParameter}" : string.Empty)}");

                if (string.IsNullOrWhiteSpace(commandResult.Message) == false)
                {
                    eventdata.Player.SendMessage(Color.LightGray, $"Error: {commandResult.Message}");
                }

                eventdata.Player.SendMessage(Color.LightGray, $"Use: {eventdata.Command.HelpSignature}");

                break;

            case CommandExecutionStatus.MissingArgument when eventdata.Command != null:
                eventdata.Player.SendMessage(Color.LightGray, string.Empty);
                eventdata.Player.SendMessage(Color.LightGray, "The command misses some arguments:");
                eventdata.Player.SendMessage(Color.LightGray, $"Use: {eventdata.Command.HelpSignature}");

                break;

            case CommandExecutionStatus.TooManyArguments when eventdata.Command != null:
                eventdata.Player.SendMessage(Color.LightGray, string.Empty);
                eventdata.Player.SendMessage(Color.LightGray, "You entered too many arguments.");
                eventdata.Player.SendMessage(Color.LightGray, $"Use: {eventdata.Command.HelpSignature}");

                break;

            default:
                eventdata.Player.SendMessage(Color.LightGray, "An error occured during command execution. Try again later.");

                break;
            }
        }
예제 #6
0
        public async Task HandleEventAsync(object?sender, CommandExecutedEvent @event)
        {
            if (@event.CommandContext.CommandRegistration == null)
            {
                // Unknown command
                return;
            }

            if (@event.CommandContext.Exception == null || @event.ExceptionHandled)
            {
                // Command was successfully executed
                await m_CommandCooldownStore.RecordExecutionAsync(@event.Actor, @event.CommandContext.CommandRegistration.Id, DateTime.Now);
            }
        }
예제 #7
0
        public void Handle(CommandExecutedEvent message)
        {
            if (message.Command.GetType().Name == "BroadcastSignalRMessage")
            {
                return;
            }

            var scheduledTask = _scheduledTaskRepository.All().SingleOrDefault(c => c.TypeName == message.Command.GetType().FullName);

            if (scheduledTask != null)
            {
                _logger.Debug("Updating last run time for: {0}", scheduledTask.TypeName);
                _scheduledTaskRepository.SetLastExecutionTime(scheduledTask.Id, DateTime.UtcNow);
            }
        }
예제 #8
0
파일: TaskModule.cs 프로젝트: Gadarr/Gadarr
 public void Handle(CommandExecutedEvent message)
 {
     BroadcastResourceChange(ModelAction.Sync);
 }
예제 #9
0
        private void OnExecutingCommand(CommandExecutedEvent @event, ref Task task)
        {
            var original = task;

            // Rocket's attempt at executing commands is hooked rather than using
            // its native event as it allows us to run asynchronous code

            async Task CheckCooldown()
            {
                if (!(@event.CommandContext.Exception is CommandNotFoundException) || R.Commands == null)
                {
                    return;
                }

                const string rocketPrefix = "rocket:";

                var commandAlias = @event.CommandContext.CommandAlias;

                if (string.IsNullOrEmpty(commandAlias))
                {
                    return;
                }

                if (commandAlias.StartsWith(rocketPrefix))
                {
                    commandAlias = commandAlias.Replace(rocketPrefix, string.Empty);
                }

                if (@event.Actor is UnturnedUser user)
                {
                    var           steamPlayer  = user.Player.SteamPlayer;
                    IRocketPlayer rocketPlayer = UnturnedPlayer.FromSteamPlayer(steamPlayer);

                    IRocketCommand command = R.Commands.GetCommand(commandAlias.ToLower());

                    if (command != null && R.Permissions.HasPermission(rocketPlayer, command))
                    {
                        string commandId = string.Format(RocketCooldownsFormat, command.Name);

                        var cooldownSpan = await m_CooldownsPluginAccessor.Instance.GetCooldownSpan(@event.Actor, commandId);

                        if (cooldownSpan.HasValue)
                        {
                            var lastExecuted = await m_CooldownManager.LastExecuted(@event.Actor, commandId);

                            if (lastExecuted.HasValue)
                            {
                                var spanSinceLast = DateTime.Now - lastExecuted.Value;

                                if (spanSinceLast < cooldownSpan)
                                {
                                    @event.CommandContext.Exception = new UserFriendlyException(
                                        m_CooldownsPluginAccessor.Instance.StringLocalizer["cooldown:command",
                                                                                           new { TimeLeft = cooldownSpan - spanSinceLast }]);

                                    @event.ExceptionHandled = false;

                                    return;
                                }
                            }

                            await m_CooldownManager.RecordExecution(@event.Actor, commandId, DateTime.Now);
                        }
                    }
                }

                await original;
            }

            task = CheckCooldown();
        }
예제 #10
0
        public async Task <ICommandContext> ExecuteAsync(ICommandActor actor, string[] args, string prefix)
        {
            if (args == null || args.Length == 0)
            {
                throw new Exception("Can not execute command with null or empty args");
            }

            var currentCommandAccessor = m_LifetimeScope.Resolve <ICurrentCommandContextAccessor>();
            var commandsRegistrations  = m_CommandStore.Commands;
            var logger = m_LifetimeScope.Resolve <ILogger <CommandExecutor> >();
            var commandContextBuilder = m_LifetimeScope.Resolve <ICommandContextBuilder>();
            var permissionChecker     = m_LifetimeScope.Resolve <IPermissionChecker>();
            var stringLocalizer       = m_LifetimeScope.Resolve <IOpenModStringLocalizer>();
            var commandContext        = commandContextBuilder.CreateContext(actor, args, prefix, commandsRegistrations);

            var commandExecutingEvent = new CommandExecutingEvent(actor, commandContext);
            await m_EventBus.EmitAsync(m_Runtime, this, commandExecutingEvent);

            if (commandExecutingEvent.IsCancelled)
            {
                return(commandExecutingEvent.CommandContext);
            }

            logger.LogInformation($"Actor {actor.Type}/{actor.DisplayName} ({actor.Id}) has executed command \"{string.Join(" ", args)}\".");

            try
            {
                if (commandContext.Exception != null)
                {
                    throw commandContext.Exception;
                }

                currentCommandAccessor.Context = commandContext;

                var permission = m_CommandPermissionBuilder.GetPermission(commandContext.CommandRegistration);
                if (!string.IsNullOrWhiteSpace(permission) && await permissionChecker.CheckPermissionAsync(actor, permission) != PermissionGrantResult.Grant)
                {
                    throw new NotEnoughPermissionException(permission, stringLocalizer);
                }

                var command = commandContext.CommandRegistration.Instantiate(commandContext.ServiceProvider);
                await command.ExecuteAsync();

                currentCommandAccessor.Context = null;
            }
            catch (UserFriendlyException ex)
            {
                await actor.PrintMessageAsync(ex.Message, Color.DarkRed);

                commandContext.Exception = ex;
            }
            catch (Exception ex)
            {
                await actor.PrintMessageAsync("An internal error occured during the command execution.", Color.DarkRed);

                logger.LogError(ex, $"Exception occured on command \"{string.Join(" ", args)}\" by actor {actor.Type}/{actor.DisplayName} ({actor.Id})");
                commandContext.Exception = ex;

#if DEBUG
                throw; // in debug mode we want to debug such exceptions instead of catching them
#endif
            }
            finally
            {
                var commandExecutedEvent = new CommandExecutedEvent(actor, commandContext);
                await m_EventBus.EmitAsync(m_Runtime, this, commandExecutedEvent);

                await commandContext.DisposeAsync();
            }

            return(commandContext);
        }
예제 #11
0
        public Task HandleEventAsync(object?sender, CommandExecutedEvent @event)
        {
            async UniTask Task()
            {
                // RocketMod commands must run on main thread
                await UniTask.SwitchToMainThread();

                if (@event.CommandContext.Exception is CommandNotFoundException && R.Commands != null)
                {
                    if (!await CheckCooldownAsync(@event))
                    {
                        return;
                    }

                    var commandAlias = @event.CommandContext.CommandAlias;
                    if (string.IsNullOrEmpty(commandAlias))
                    {
                        return;
                    }

                    var isRocketPrefixed = commandAlias.StartsWith(c_RocketPrefix);
                    if (isRocketPrefixed)
                    {
                        commandAlias = s_PrefixRegex.Replace(commandAlias, string.Empty, 1);
                    }

                    IRocketPlayer rocketPlayer;
                    if (@event.Actor is UnturnedUser user)
                    {
                        var steamPlayer = user.Player.SteamPlayer;
                        if (!(bool)s_CheckPermissionsMethod.Invoke(null, new object[] { steamPlayer, $"/{commandAlias}" }))
                        {
                            // command doesnt exist or no permission
                            @event.ExceptionHandled = true;
                            return;
                        }

                        rocketPlayer = UnturnedPlayer.FromSteamPlayer(steamPlayer);
                    }
                    else if (@event.Actor.Type.Equals(KnownActorTypes.Console, StringComparison.OrdinalIgnoreCase))
                    {
                        rocketPlayer = new ConsolePlayer();

                        var command = R.Commands.GetCommand(commandAlias.ToLower(CultureInfo.InvariantCulture));
                        if (command == null)
                        {
                            return;
                        }
                    }
                    else
                    {
                        // unsupported user; do not handle
                        return;
                    }

                    var commandLine = @event.CommandContext.GetCommandLine();
                    if (isRocketPrefixed)
                    {
                        commandLine = s_PrefixRegex.Replace(commandLine, string.Empty, count: 1);
                    }

                    R.Commands.Execute(rocketPlayer, commandLine);
                    @event.ExceptionHandled = true;
                }
            }

            return(Task().AsTask());
        }
예제 #12
0
        public async Task <ICommandContext> ExecuteAsync(ICommandActor actor, string[] args, string prefix)
        {
            if (args == null || args.Length == 0)
            {
                throw new Exception("Cannot execute command with null or empty args.");
            }

            m_Logger.LogInformation("Actor {ActorType}/{ActorName} has executed command \"{Command}\"",
                                    actor.Type, actor.FullActorName, string.Join(" ", args));

            var currentCommandAccessor = m_LifetimeScope.Resolve <ICurrentCommandContextAccessor>();
            var commandContextBuilder  = m_LifetimeScope.Resolve <ICommandContextBuilder>();
            var stringLocalizer        = m_LifetimeScope.Resolve <IOpenModStringLocalizer>();

            var commandsRegistrations = await m_CommandStore.GetCommandsAsync();

            var commandContext        = commandContextBuilder.CreateContext(actor, args, prefix, commandsRegistrations);
            var commandExecutingEvent = new CommandExecutingEvent(actor, commandContext);
            await m_EventBus.EmitAsync(m_Runtime, this, commandExecutingEvent);

            if (commandExecutingEvent.IsCancelled)
            {
                return(commandExecutingEvent.CommandContext);
            }

            try
            {
                if (commandContext.Exception != null)
                {
                    throw commandContext.Exception;
                }

                currentCommandAccessor.Context = commandContext;

                var permission        = m_CommandPermissionBuilder.GetPermission(commandContext.CommandRegistration !);
                var permissionChecker = m_Runtime.LifetimeScope.Resolve <IPermissionChecker>();

                if (!string.IsNullOrWhiteSpace(permission) && await permissionChecker.CheckPermissionAsync(actor, permission) != PermissionGrantResult.Grant)
                {
                    throw new NotEnoughPermissionException(stringLocalizer, permission);
                }

                var sw = new Stopwatch();
                sw.Start();
                var command = commandContext.CommandRegistration !.Instantiate(commandContext.ServiceProvider);
                await command.ExecuteAsync();

                m_Logger.LogDebug("Command \"{Command}\" executed in {Ms}ms",
                                  string.Join(" ", args), sw.ElapsedMilliseconds);

                currentCommandAccessor.Context = null;
            }
            catch (UserFriendlyException ex)
            {
                commandContext.Exception = ex;
            }
            catch (Exception ex)
            {
                commandContext.Exception = ex;
            }
            finally
            {
                var commandExecutedEvent = new CommandExecutedEvent(actor, commandContext);
                await m_EventBus.EmitAsync(m_Runtime, this, commandExecutedEvent);

                if (commandContext.Exception != null && !commandExecutedEvent.ExceptionHandled)
                {
                    if (commandContext.Exception is UserFriendlyException)
                    {
                        await actor.PrintMessageAsync(commandContext.Exception.Message, Color.DarkRed);
                    }
                    else
                    {
                        await actor.PrintMessageAsync("An internal error occured during the command execution.", Color.DarkRed);

                        m_Logger.LogError(commandContext.Exception,
                                          "Exception occured on command \"{Command}\" by actor {ActorType}/{ActorName} ({ActorId})",
                                          string.Join(" ", args), actor.Type, actor.DisplayName, actor.Id);
                    }
                }

                await commandContext.DisposeAsync();
            }

            return(commandContext);
        }
예제 #13
0
 private static void ExecutingCommand(CommandExecutedEvent @event, ref Task __result)
 {
     OnExecutingCommand?.Invoke(@event, ref __result);
 }