예제 #1
0
        private async Task ExecuteReflectionCommand(IPlayer player, ReflectionCommand reflectionCommand, string commandText)
        {
            var commandParameters = reflectionCommand.MethodInfo.GetParameters();
            var arguments         = commandText.Split(' ', commandParameters.Length, StringSplitOptions.RemoveEmptyEntries);

            if (commandParameters.Count(x => x.HasDefaultValue == false) > arguments.Length)
            {
                OnCommandError(player, commandText, CommandError.MissingArguments, "The given command lacks arguments!");

                return;
            }

            var invokingArguments = new object[commandParameters.Length];

            invokingArguments[0] = player;

            if (ProcessArguments(arguments, commandParameters, invokingArguments) == false)
            {
                OnCommandError(player, commandText, CommandError.TypeParsingFailed, $"Type conversion failed. Command parameters are: {reflectionCommand.GetParameterList()}");

                return;
            }

            try
            {
                await reflectionCommand.Invoke(invokingArguments);
            }
            catch (Exception e)
            {
                _logger.Error($"An error occured when player {await player.GetNameAsync()} executed command: {reflectionCommand.Name}: ", e);
            }
        }
예제 #2
0
        public void RegisterHandler(ICommandHandler handler)
        {
            Contract.NotNull(handler, nameof(handler));

            var commandMethods = handler
                                 .GetType()
                                 .GetMethods()
                                 .Where(m => m.GetCustomAttributes(typeof(CommandAttribute), true).Any());

            foreach (var commandMethod in commandMethods)
            {
                var attribute = commandMethod.GetCustomAttribute <CommandAttribute>();

                if (string.IsNullOrEmpty(attribute.Name))
                {
                    _logger.Warn($"Skipping method {commandMethod.Name} because of invalid command name.");

                    continue;
                }

                if (commandMethod.ReturnType != typeof(Task))
                {
                    _logger.Warn($"Command {attribute.Name}: Return type {commandMethod.ReturnType} is invalid, {typeof(Task)} expected!");

                    continue;
                }

                if (commandMethod.IsStatic)
                {
                    _logger.Warn($"Command {attribute.Name}: Static methods are not allowed!");

                    continue;
                }

                CommandInformation command;
                var commandDelegate = (CommandDelegate)Delegate.CreateDelegate(typeof(CommandDelegate), handler, commandMethod, false);
                if (commandDelegate != null)
                {
                    command = new DelegateCommand(attribute.Name, commandDelegate, handler);
                }
                else
                {
                    command = new ReflectionCommand(attribute.Name, handler, commandMethod);
                }

                if (_commands.TryAdd(attribute.Name, command) == false)
                {
                    _logger.Warn($"Command {attribute.Name}: Could not register command of method \"{commandMethod.Name}\" in \"{commandMethod.DeclaringType}\", maybe command-name is already in use!");
                }
            }
        }