Class: CommandrbBot

Inherits:
Object
  • Object
show all
Defined in:
lib/helper.rb,
lib/commandrb.rb

Defined Under Namespace

Modules: Helper

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(init_hash) ⇒ CommandrbBot

Returns a new instance of CommandrbBot.



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
62
63
64
65
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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
# File 'lib/commandrb.rb', line 33

def initialize(init_hash)

  # Setup the variables for first use.
  @commands = {}
  @prefixes = []
  @config = init_hash

  # Load sane defaults for options that aren't specified.

  # @config[:prefix_type] = 'rescue' if @config[:prefix_type].nil?
  @config[:typing_default] = false if @config[:typing_default].nil?
  @config[:selfbot] =  false if  @config[:selfbot].nil?
  @config[:delete_activators] = false if @config[:delete_activators].nil?

  if @config[:token].nil? or init_hash[:token] == ''
    raise 'No token supplied in init hash!'
    return false
  end

  init_parse_self = init_hash[:parse_self] rescue nil
  init_type = @config[:type]

  if init_type == :bot
    if init_hash[:client_id].nil?
      raise 'No client ID or invalid client ID supplied in init hash!'
      return false
    end
  end

  @config[:owners] = init_hash[:owners]
  @config[:owners] = [] if @config[:owners].nil?

  @prefixes = init_hash[:prefixes]

  @bot = Discordrb::Bot.new(
      token: @config[:token],
      client_id: @config[:client_id],
      parse_self: init_parse_self,
      type: @config[:type]
  )

  unless init_hash[:ready].nil?
    @bot.ready do |event|
      event.bot.game = @config[:game] unless config[:game].nil?
      init_hash[:ready].call(event)
    end
  end


  # Command processing
  @bot.message do |event|
    @finished = false
    @command = nil
    @event = nil
    @chosen = nil
    @args = nil
    @rawargs = nil
    @continue = false
    @prefixes.each { |prefix|
      break if @finished
      if event.message.content.start_with?(prefix)

        @commands.each { | key, command |
          break if @finished
          puts ":: Considering #{key.to_s}"  if @debug_mode
          triggers =  command[:triggers].nil? ? [key.to_s] : command[:triggers]

          triggers.each { |trigger|
            @activator = prefix + trigger.to_s
            puts @activator if @debug_mode
            @activator = @activator.downcase
            if event.message.content.downcase.start_with?(@activator)
              puts "Prefix matched! #{@activator}" if @debug_mode

              # Continue only if you've already chosen a choice.
              unless @chosen.nil?
                # If the new activator begins with the chosen one, then override it.
                # Example: sh is chosen, shell is the new one.
                # In this example, shell would override sh, preventing ugly bugs.
                if @activator.start_with?(@chosen)
                  puts "#{@activator} just overrode #{@chosen}" if @debug_mode
                  @chosen = @activator
                # Otherwhise, just give up.
                else
                  puts "Match failed..." if @debug_mode
                  next
                end
              # If you haven't chosen yet, get choosing!
              else
                  puts "First match obtained!" if @debug_mode
                  @continue = true
                  @chosen = @activator
              end
            end
          }
          
          puts "Result: #{@chosen}" if @debug_mode

          next if !@continue
          puts "Final esult: #{@chosen}" if @debug_mode

          break if @config[:selfbot] && event.user.id != @bot.profile.id

          # Command flag defaults
          command[:catch_errors] = @config[:catch_errors] if command[:catch_errors].nil?
          command[:owners_only] = false if command[:owners_only].nil?
          command[:max_args] = 2000 if command[:max_args].nil?
          command[:server_only] = false if command[:server_only].nil?
          command[:typing] = @config[:typing_default] if command[:typing_default].nil?
          command[:delete_activator] = @config[:delete_activators] if command[:delete_activator].nil?

          # If the command is set to owners only and the user is not the owner, show error and abort.
          puts "[DEBUG] Command being processed: '#{command}'" if @debug_mode
          puts "[DEBUG] Owners only? #{command[:owners_only]}" if @debug_mode
          if command[:owners_only]
            if !@config[:owners].include?(event.user.id)
              event.channel.send_message('', false,
                Helper.error_embed(
                 error: "You don't have permission for that!\nOnly owners are allowed to access this command.",
                 footer: "Command: `#{event.message.content}`",
                 colour: 0xFA0E30,
                 code_error: false
                )
              )
              puts 'Were returning!'
              @finished = true
              next
            end
          end

          # If the settings are to delete activating messages, then do that.
          # I'm *hoping* this doesn't cause issues with argument extraction.
          event.message.delete if command[:delete_activator]

          # If the command is only for use in servers, display error and abort.
          if command[:server_only] && event.channel.private?
            # For selfbots, a fancy embed will be used. WIP.
            if @config[:selfbot]
              event.channel.send_embed do |embed|
                embed.colour = 0x221461
                embed.title = '❌ An error has occured!'
                embed.description = 'This command can only be used in servers!'
                embed.footer = Discordrb::Webhooks::EmbedFooter.new(text: "Command: '#{event.message.content}'")
              end
            else
              # If its not a selfbot, an ordinary message will be shown, may be changed to embed later.
              event.respond('❌ This command will only work in servers!')
            end
            # Abort!
            @finished = true
            next
          end

          # If the user is a bot and the command is set to not pass bots OR the user is a bot and the global config is to not parse bots...
          # ...then abort :3
          if (event.user.bot_account? && command[:parse_bots] == false) || (event.user.bot_account? && @config[:parse_bots] == false)
            # Abort!
            @finished = true
            next
          end

          # If the config is setup to show typing messages, then do so.
          event.channel.start_typing if command[:typing]

          args = event.message.content.split(' ')
          # Parse args if args exist !
          begin 
            spaces = 1
            # Prefixes with spaces are special and need to be parsed differently : )
            if prefix.include? " "
              spaces += prefix.count(' ')
              args = event.message.content.slice!(args[0].size + args[1].size + spaces, event.message.content.size)
            else
              args = event.message.content.slice!(args[0].size + spaces, event.message.content.size)
            end
            # Split the argmuents into an array for easy usage but keep the raw args !!
            rawargs = args
            args = args.split(/ /)
          rescue NoMethodError # Not the most elegant solution but it'll do. TODO: Make a more elegant solution.
            args = []
          end


          # Check the number of args for the command.
          unless command[:max_args].nil?
            if command[:max_args] > 0 && args.length > command[:max_args]
              # May be replaced with an embed.
              event.channel.send_message('', false,
                  Helper.error_embed(
                   error: "Too many arguments! \nMax arguments: `#{command[:max_args]}`",
                   footer: "Command: `#{event.message.content}`",
                   colour: 0xFA0E30,
                   code_error: false
                  )
                )
              @finished = true
              break
            end
          end
          
          unless command[:required_permissions].nil?
            command[:required_permissions].each { |x|
              unless event.user.on(event.server).permission?(x,event.channel)
                event.channel.send_message('', false,
                  Helper.error_embed(
                   error: "You don't have permission for that!\nPermission required: `#{x.to_s}`",
                   footer: "Command: `#{event.message.content}`",
                   colour: 0xFA0E30,
                   code_error: false
                  )
                )
                @finished = true
                break
              end
            }
          end
          
          unless @finished
            # If the command is configured to catch all errors, thy shall be done.
            if !command[:catch_errors] || @config['catch_errors']
              # Run the command code!
              command[:code].call(event, args, rawargs)
            else
              # Run the command code, but catch all errors and output accordingly.
              begin
                command[:code].call(event, args, rawargs)
              rescue Exception => e
                event.respond("❌ An error has occured!! ```ruby\n#{e}```Please contact the bot owner with the above message for assistance.")
              end
            end
          end

          # All done here.
          puts "Finished!! Executed command: #{@chosen}" if @debug_mode
          @command = command
          @event = event
          @args = args
          @rawargs = rawargs
          @finished = true
          break
        }
      end
    }
  end
end

Instance Attribute Details

#botObject

Needed to run the bot, or create custom events.



11
12
13
# File 'lib/commandrb.rb', line 11

def bot
  @bot
end

#commandsObject

Can manually manipulate commands using this.



14
15
16
# File 'lib/commandrb.rb', line 14

def commands
  @commands
end

#configObject

Be able to adjust the config on the fly.



8
9
10
# File 'lib/commandrb.rb', line 8

def config
  @config
end

#prefixesObject

Lets you change global prefixes while the bot is running (Not recommended!)



17
18
19
# File 'lib/commandrb.rb', line 17

def prefixes
  @prefixes
end

Instance Method Details

#add_command(name, attributes = {}) ⇒ Object



20
21
22
# File 'lib/commandrb.rb', line 20

def add_command(name, attributes = {})
  @commands[name.to_sym] = attributes
end

#remove_command(name) ⇒ Object



24
25
26
27
28
29
30
31
# File 'lib/commandrb.rb', line 24

def remove_command(name)
  begin
    @commands.delete(name)
  rescue
    return false
  end
  true
end