Module: OnyxCord::Commands::Bot::Execution

Included in:
OnyxCord::Commands::Bot
Defined in:
lib/onyxcord/commands/bot/execution.rb

Overview

Command execution and dispatch logic for the command bot.

Instance Method Summary collapse

Instance Method Details

#arg_check(args, types = nil, server = nil) ⇒ Object

Transforms an array of string arguments based on types array. For example, ['1', '10..14'] with types [Integer, Range] would turn into [1, 10..14].



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# File 'lib/onyxcord/commands/bot/execution.rb', line 66

def arg_check(args, types = nil, server = nil)
  return args unless types

  args.each_with_index.map do |arg, i|
    next arg if types[i].nil? || types[i] == String

    if types[i] == Integer
      Integer(arg, 10, exception: false)
    elsif types[i] == Float
      Float(arg, exception: false)
    elsif types[i] == Time
      begin
        Time.parse arg
      rescue ArgumentError
        nil
      end
    elsif [TrueClass, FalseClass].include?(types[i])
      if arg.casecmp('true').zero? || arg.downcase.start_with?('y')
        true
      elsif arg.casecmp('false').zero? || arg.downcase.start_with?('n')
        false
      end
    elsif types[i] == Symbol
      arg.to_sym
    elsif types[i] == Encoding
      begin
        Encoding.find arg
      rescue ArgumentError
        nil
      end
    elsif types[i] == Regexp
      begin
        Regexp.new arg
      rescue ArgumentError
        nil
      end
    elsif types[i] == Rational
      Rational(arg, exception: false)
    elsif types[i] == Range
      begin
        if arg.include? '...'
          Range.new(*arg.split('...').map(&:to_i), true)
        elsif arg.include? '..'
          Range.new(*arg.split('..').map(&:to_i))
        end
      rescue ArgumentError
        nil
      end
    elsif types[i] == NilClass
      nil
    elsif [OnyxCord::User, OnyxCord::Role, OnyxCord::Emoji].include? types[i]
      result = parse_mention arg, server
      result if result.instance_of? types[i]
    elsif types[i] == OnyxCord::Invite
      resolve_invite_code arg
    elsif types[i].respond_to?(:from_argument)
      begin
        types[i].from_argument arg
      rescue StandardError
        nil
      end
    else
      raise ArgumentError, "#{types[i]} doesn't implement from_argument"
    end
  end
end

#command_aliases(name) ⇒ Array<CommandAlias>

Returns all aliases for the command with the given name

Parameters:

  • name (Symbol)

    the name of the Command

Returns:



9
10
11
12
13
# File 'lib/onyxcord/commands/bot/execution.rb', line 9

def command_aliases(name)
  commands.values.select do |command|
    command.is_a?(OnyxCord::Commands::CommandAlias) && command.aliased_command.name == name
  end
end

#execute_command(name, event, arguments, chained = false, check_permissions = true) ⇒ String?

Executes a particular command on the bot. Mostly useful for internal stuff, but one can never know.

Parameters:

  • name (Symbol)

    The command to execute.

  • event (CommandEvent)

    The event to pass to the command.

  • arguments (Array<String>)

    The arguments to pass to the command.

  • chained (true, false) (defaults to: false)

    Whether or not it should be executed as part of a command chain. If this is false, commands that have chain_usable set to false will not work.

  • check_permissions (true, false) (defaults to: true)

    Whether permission parameters such as required_permission or permission_level should be checked.

Returns:

  • (String, nil)

    the command's result, if there is any.



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/onyxcord/commands/bot/execution.rb', line 25

def execute_command(name, event, arguments, chained = false, check_permissions = true)
  debug("Executing command #{name} with arguments #{arguments}")
  return unless @commands

  command = @commands[name]
  command = command.aliased_command if command.is_a?(OnyxCord::Commands::CommandAlias)
  return unless !check_permissions || channels?(event.channel, @attributes[:channels]) ||
                (command && !command.attributes[:channels].nil?)

  unless command
    if @attributes[:command_doesnt_exist_message]
      message = @attributes[:command_doesnt_exist_message]
      message = message.call(event) if message.respond_to?(:call)
      event.respond message.gsub('%command%', name.to_s) if message
    end
    return
  end
  return unless !check_permissions || channels?(event.channel, command.attributes[:channels])

  arguments = arg_check(arguments, command.attributes[:arg_types], event.server) if check_permissions
  if (check_permissions &&
     permission?(event.author, command.attributes[:permission_level], event.server) &&
     required_permissions?(event.author, command.attributes[:required_permissions], event.channel) &&
     required_roles?(event.author, command.attributes[:required_roles]) &&
     allowed_roles?(event.author, command.attributes[:allowed_roles])) ||
     !check_permissions
    event.command = command
    result = command.call(event, arguments, chained, check_permissions)
    stringify(result)
  else
    event.respond command.attributes[:permission_message].gsub('%name%', name.to_s) if command.attributes[:permission_message]
    nil
  end
rescue OnyxCord::Errors::NoPermission
  event.respond @attributes[:no_permission_message] unless @attributes[:no_permission_message].nil?
  raise
end

#simple_execute(chain, event) ⇒ String?

Executes a command in a simple manner, without command chains or permissions.

Parameters:

  • chain (String)

    The command with its arguments separated by spaces.

  • event (CommandEvent)

    The event to pass to the command.

Returns:

  • (String, nil)

    the command's result, if there is any.



138
139
140
141
142
143
# File 'lib/onyxcord/commands/bot/execution.rb', line 138

def simple_execute(chain, event)
  return nil if chain.empty?

  args = chain.split(' ')
  execute_command(args[0].to_sym, event, args[1..])
end