From ada8ac47c34f79d722b8063fc802293547347d2e Mon Sep 17 00:00:00 2001 From: Lucio Delelis Date: Sat, 2 Dec 2017 14:15:37 -0300 Subject: [PATCH 1/5] Add rubocop with overwritten standards --- .rubocop.yml | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 .rubocop.yml diff --git a/.rubocop.yml b/.rubocop.yml new file mode 100644 index 0000000..8c5f8d6 --- /dev/null +++ b/.rubocop.yml @@ -0,0 +1,13 @@ +inherit_from: + - https://raw.githubusercontent.com/meew0/discordrb/master/.rubocop.yml + +Metrics/LineLength: + Max: 119 + +Style/GlobalVars: + AllowedVariables: + - $config + - $pasta + - $figlet + - $user_type + - $bot From 77bac9754033e7fb8b0f00ac817984723ff03343 Mon Sep 17 00:00:00 2001 From: Lucio Delelis Date: Sat, 2 Dec 2017 14:41:16 -0300 Subject: [PATCH 2/5] Major changes for rubocop complaince. All commands tested with a test bot on my personal server. --- config_example.yaml | 12 ++++--- lib/admin.rb | 45 ++++++++++++------------- lib/fun.rb | 81 +++++++++++++++++++++------------------------ lib/patches.rb | 9 ++--- lib/utilities.rb | 42 +++++++++++------------ main.rb | 49 +++++++++++++-------------- 6 files changed, 115 insertions(+), 123 deletions(-) diff --git a/config_example.yaml b/config_example.yaml index 7083377..bcac924 100644 --- a/config_example.yaml +++ b/config_example.yaml @@ -1,8 +1,12 @@ --- token: serverID: '' -sudoersRole: '' -timeoutRole: '' -figletFont: '' #a font name from the fonts folder minus the .flf +roles: + sudoersRole: '' + timeoutRole: '' + nonfsfRole: '' + botdevRole: '' +infoFile: '' +figletFont: '' # a font name from the fonts folder minus the .flf prefix: '' -lusersList: '' #a sequence of stringos +lusersList: '' # a sequence of strings diff --git a/lib/admin.rb b/lib/admin.rb index a8232ad..e57f55c 100644 --- a/lib/admin.rb +++ b/lib/admin.rb @@ -1,41 +1,38 @@ +# Implements administration commands that are unavailable to regular users. module Admin extend Discordrb::Commands::CommandContainer command(:clear, - description: "Clears N amount of messages. If no arguments are " \ - "specified, 100 messages will be cleared. " \ - "Requires superuser", - help_available: false) \ - do |event, *args| - unless $userType != 'sudoer' - event.channel.send_message("Invalid amount") && - break if args[0].to_i > 100 - toDelete = event.channel.history(args.empty? ? 100 : args[0].to_i+1) - event.channel.delete_messages(toDelete) - "Clearing..." + description: 'Clears N amount of messages. If no arguments are ' \ + 'specified, 100 messages will be cleared. ' \ + 'Requires superuser', + help_available: false) do |event, *args| + if $user_type == 'sudoer' + event.channel.send_message('Invalid amount') && break if args[0].to_i > 100 + to_delete = event.channel.history(args.empty? ? 100 : args[0].to_i + 1) + event.channel.delete_messages(to_delete) else - "Permission denied." + event.channel.send_message('Permission denied.') end end command(:timeout, - description: "Times out a user for N seconds. Requires superuser", + description: 'Times out a user for N seconds. Requires superuser', min_args: 2, - usage: "[user to timeout] [seconds of timeout]", - help_available: false) \ - do |event, *args| - unless $userType != 'sudoer' - timeOut = fork do + usage: '[user to timeout] [seconds of timeout]', + help_available: false) do |event, *args| + if $user_type == 'sudoer' + time_out = fork do user = event.message.mentions[0].on($config['serverID']) - user.add_role($config['timeoutRole']) + user.add_role($config['roles']['timeoutRole']) sleep args[1].to_i user.remove_role($config['timeoutRole']) - "#{user.name} timed out for #{args[1].to_i}" + event.channel.send_message("#{user.name} timed out for #{args[1].to_i}") end - puts Process.detach(timeOut) #This puts is imporant so the thread ID - else #Doesn't get outputted by the bot - "Permission denied." + Process.detach(time_out) + return + else + event.channel.send_message('Permission denied.') end - end end diff --git a/lib/fun.rb b/lib/fun.rb index dbe0b3f..49fb1b5 100644 --- a/lib/fun.rb +++ b/lib/fun.rb @@ -1,72 +1,65 @@ +# Implements fluff commands that serve no real use module Fun extend Discordrb::Commands::CommandContainer command(:aesthic, - description: "Makes a message A E S T H E T I C", - usage: "[text to convert]", - min_args: 1) \ - do |event, *args| - args.join(' ').to_fullwidth + description: 'Makes a message A E S T H E T I C', + usage: '[text to convert]', + min_args: 1) do |event, *args| + event.channel.send_message(args.join(' ').to_fullwidth) end command(:step, - description: "Show your soles to someone or something", - usage: "[text]", - min_args: 1) \ - do |event, *args| + description: 'Show your soles to someone or something', + usage: '[text]', + min_args: 1) do |event, *args| args.to_a.delete_at(0) if args.include?('on') - "<@#{event.author.id.to_s}> steps on #{args.join(' ')}" + event.channel.send_message("<@#{event.author.id}> steps on #{args.join(' ')}") end command(:slap, - description: "Hit someone or something", - usage: "[text]") \ - do |event, *args| - event.channel.send_message("<@#{event::author::id.to_s}> slaps " \ - "#{args.join(' ')} around a bit with a large trout") + description: 'Hit someone or something', + usage: '[text]') do |event, *args| + event.channel.send_message("<@#{event.author.id}> slaps #{args.join(' ')} around a bit with a large trout") end command(:figlet, - description: "Turns a message into big ASCII art letters", - usage: "[text]", - min_args: 1) \ - do |event, *args| - "```" + $figlet[args.join('')] + "```" + description: 'Turns a message into big ASCII art letters', + usage: '[text]', + min_args: 1) do |event, *args| + event.channel.send_message('```' + $figlet[args.join('')] + '```') end command(:cowsay, - description: "Wraps a message with an ASCII art cow", - usage: "[text]", - min_args: 1) \ - do |event, *args| - inputtext = args.join(' ').gsub("```", ''); - renderedtext = Cowsay.say(inputtext, 'cow') - chunkedtext = "" - until renderedtext.empty? - sliced = renderedtext.slice(0..1990) - lastindex = sliced.length - 1 - lastline = sliced.lines.last - unless lastline.end_with? '\n' or renderedtext.length == sliced.length - lastindex -= lastline.length + description: 'Wraps a message with an ASCII art cow', + usage: '[text]', + min_args: 1) do |event, *args| + input_text = args.join(' ').gsub('```', '') + rendered_text = Cowsay.say(input_text, 'cow') + chunked_text = '' + until rendered_text.empty? + sliced = rendered_text.slice(0..1990) + last_index = sliced.length - 1 + last_line = sliced.lines.last + unless last_line.end_with?('\n') || rendered_text.length == sliced.length + last_index -= last_line.length end - chunkedtext << "```\n" + renderedtext.slice!(0..lastindex)+ "\n```" \ - + " " * lastline.length + "\n" + chunked_text << "```\n" + rendered_text.slice!(0..last_index) + "\n```" \ + + ' ' * last_line.length + "\n" end - chunkedtext + event.channel.send_message(chunked_text) end command(:me, - description: "Executes a self action", - usage: "[text]", - min_args: 1) \ - do |event, *args| + description: 'Executes a self action', + usage: '[text]', + min_args: 1) do |event, *args| event.channel.delete_message(event.channel.history(1)[0]) - "<@#{event.user.id.to_s}> *#{args.join(' ')}*" + event.channel.send_message("<@#{event.user.id}> *#{args.join(' ')}*") end command(:fortune, - description: "Outputs a random fortune / divination / bad joke") \ - do |event| - "```" + FortuneGem.give_fortune + "```" + description: 'Outputs a random fortune / divination / bad joke') do |event| + event.channel.send_message('```' + FortuneGem.give_fortune + '```') end end diff --git a/lib/patches.rb b/lib/patches.rb index ab0e0f9..bbaad10 100644 --- a/lib/patches.rb +++ b/lib/patches.rb @@ -1,7 +1,8 @@ -#allow output from commands to exceed 2000 chars +# Allow output from commands to exceed 2000 chars module Discordrb::Commands + # Overwrite of the CommandBot to monkey patch command length class CommandBot - def execute_chain(chain, event) + def execute_chain(chain, event) t = Thread.new do @event_threads << t Thread.current[:discordrb_name] = "ct-#{@current_thread += 1}" @@ -9,14 +10,14 @@ def execute_chain(chain, event) debug("Parsing command chain #{chain}") result = @attributes[:advanced_functionality] ? CommandChain.new(chain, self).execute(event) : simple_execute(chain, event) result = event.drain_into(result) - + if event.file event.send_file(event.file, caption: result) else unless result.nil? || result.empty? Discordrb.split_message(result).each do |chunk| event.respond chunk - end + end end end rescue => e diff --git a/lib/utilities.rb b/lib/utilities.rb index 318329b..b6e8d26 100644 --- a/lib/utilities.rb +++ b/lib/utilities.rb @@ -1,54 +1,54 @@ +# Implements utility commands for everyone's use module Utilities extend Discordrb::Commands::CommandContainer command(:random, - description: "Picks a random number.", - usage: " ", - min_args: 2) \ - do |event| + description: 'Picks a random number.', + usage: ' ', + min_args: 2) do |event| # Parse the message and keep all parts but the command # ["::random 1 2 4 5 -5"] => ["1", "2", "4", "5", "-5"] - args = (event.message.content.split (' '))[1 .. -1] + args = event.message.content.split(' ')[1..-1] # Args to integer - input = Array.new(args.size){ |i| args[i].to_i } + input = Array.new(args.size) { |i| args[i].to_i } case input.size when 0 # Integer "limits" (there's no such thing in ruby though) - min = -(2**(0.size * 8 -2)) + min = -(2**(0.size * 8 - 2)) max = min.abs when 1 min = 0 max = 0 # If one args is given, the result will be of the same sign as the arg - input[0] >= 0? max = input[0] : min = input[0] + input[0] >= 0 ? max = input[0] : min = input[0] else min = input.min max = input.max end - rand(min .. max) + rand(min..max) end command(:echo, - description: "Echoes text.", - usage: "[text to echo]", - min_args: 1) \ - do |event, *args| - args.join(' ') + description: 'Echoes text.', + usage: '[text to echo]', + min_args: 1) do |event, *args| + event.channel.send_message(args.join(' ')) end command(:lusers, - description: "Prints the amount of lusers currently online.", - usage: "!lusers") \ - do |event| - "Amount of lusers currently #{$config['lusersList'].sample}: #{event.server.online_users(include_idle: true).length.to_s}" + description: 'Prints the amount of lusers currently online.', + usage: '!lusers') do |event| + event.channel.send_message('Amount of lusers currently ' \ + "#{$config['lusersList'].sample}:" \ + "#{event.server.online_users(include_idle: true).length}") end command(:checksudo, description: "Prints if you're a sudoer", - usage: "!checksudo") \ - do |event| - "You are a #{event.user.roles.include?($config['sudoersRole'])?'sudoer':'regular user'}." + usage: '!checksudo') do |event| + event.channel.send_message('You are a ' \ + "#{event.user.roles.include?($config['roles']['sudoersRole']) ? 'sudoer' : 'regular user'}.") end end diff --git a/main.rb b/main.rb index 2e76e99..24bdd6e 100755 --- a/main.rb +++ b/main.rb @@ -13,60 +13,57 @@ require_relative 'lib/admin' $config = YAML.load_file('config.yaml') -$infofile = $config['infoFile'] $pasta = YAML.load_file('pasta.yaml') -#Figlet initialization -$font = Figlet::Font.new("fonts/#{$config['figletFont']}.flf") -$figlet = Figlet::Typesetter.new($font) +# Figlet initialization +$figlet = Figlet::Typesetter.new(Figlet::Font.new("fonts/#{$config['figletFont']}.flf")) $bot = Discordrb::Commands::CommandBot.new(token: $config['token'], - prefix: $config['prefix'], - advanced_functionality: true, - spaces_allowed: true, - chain_delimiter: '|', - previous: '-', - ignore_bots: true, - command_doesnt_exist_message: "zsh: command not found") + prefix: $config['prefix'], + advanced_functionality: true, + spaces_allowed: true, + chain_delimiter: '|', + previous: '-', + ignore_bots: true, + command_doesnt_exist_message: 'zsh: command not found') $bot.include! Utilities $bot.include! Fun $bot.include! Admin -$userType = 'normal' +$user_type = 'normal' -$bot.command :sudo \ -do |event, *args| - if event.author.roles.select{|role| role.id == $config['sudoersRole']}.length > 0 - runCommand = args[0] - args.slice!(0) - $userType = 'sudoer' - $bot.execute_command(runCommand.to_sym, event, args) - $userType = 'normal' +$bot.command :sudo do |event, *args| + if event.author.roles.select { |role| role.id == $config['roles']['sudoersRole'] }.empty? + event.channel.send_message("<@#{event.author.id}> is not in the sudoers file. This incident will be reported.") else - event.channel.send_message("<@#{event.author.id.to_s}> is not in the sudoers file. This incident will be reported.") + run_command = args[0] + args.slice!(0) + $user_type = 'sudoer' + $bot.execute_command(run_command.to_sym, event, args) + $user_type = 'normal' end - nil + break # Avoids garbage messages end $pasta.keys.each do |pasta| # Slightly improved $bot.command pasta.to_sym do |event, *args| catch :RegexError do sed = [] - args.each { |string| string.split('/').each { |subs| sed.push(subs)}} - $pasta = YAML.load_file('pasta.yaml') + args.each { |string| string.split('/').each { |subs| sed.push(subs) } } + $pasta = YAML.load_file('pasta.yaml') # Required to reload the pastas message = $pasta[pasta] unless sed.empty? sed.each_slice(2) do |match, replace| begin message.gsub!(/#{match}/i, replace || '') rescue RegexpError - "Error: Invalid Regex" + event.channel.send_message('Error: Invalid Regex') throw :RegexError end end end - message + event.channel.send_message(message) end end end From 80dc80359773ae21e761ea6f5ad517818e046f1f Mon Sep 17 00:00:00 2001 From: Lucio Delelis Date: Sat, 2 Dec 2017 15:03:25 -0300 Subject: [PATCH 3/5] Added self role asignation for users Also rolled back a roles change to keep backwards compatibility --- config_example.yaml | 10 +++++----- lib/admin.rb | 2 +- lib/utilities.rb | 20 +++++++++++++++++++- main.rb | 2 +- 4 files changed, 26 insertions(+), 8 deletions(-) diff --git a/config_example.yaml b/config_example.yaml index bcac924..2eefb8f 100644 --- a/config_example.yaml +++ b/config_example.yaml @@ -1,11 +1,11 @@ --- token: serverID: '' -roles: - sudoersRole: '' - timeoutRole: '' - nonfsfRole: '' - botdevRole: '' +sudoersRole: '' +timeoutRole: '' +selfRoles: + nonfsf: '' + botdev: '' infoFile: '' figletFont: '' # a font name from the fonts folder minus the .flf prefix: '' diff --git a/lib/admin.rb b/lib/admin.rb index e57f55c..4053ea0 100644 --- a/lib/admin.rb +++ b/lib/admin.rb @@ -24,7 +24,7 @@ module Admin if $user_type == 'sudoer' time_out = fork do user = event.message.mentions[0].on($config['serverID']) - user.add_role($config['roles']['timeoutRole']) + user.add_role($config['timeoutRole']) sleep args[1].to_i user.remove_role($config['timeoutRole']) event.channel.send_message("#{user.name} timed out for #{args[1].to_i}") diff --git a/lib/utilities.rb b/lib/utilities.rb index b6e8d26..05e49bf 100644 --- a/lib/utilities.rb +++ b/lib/utilities.rb @@ -49,6 +49,24 @@ module Utilities description: "Prints if you're a sudoer", usage: '!checksudo') do |event| event.channel.send_message('You are a ' \ - "#{event.user.roles.include?($config['roles']['sudoersRole']) ? 'sudoer' : 'regular user'}.") + "#{event.user.roles.include?($config['sudoersRole']) ? 'sudoer' : 'regular user'}.") + end + + command(:getrole, + description: 'Adds a self-assignable role', + usage: '', + max_args: 1) do |event, *args| + role = args.join('') + if $config['selfRoles'].key?(role) + if event.author.role?(role) + event.channel.send_message('This user has already assigned that role to himself!') + return + end + event.author.add_role($config['selfRoles'][role]) + event.channel.send_message("<@#{event.author.id}> was assigned the role #{role}!") + else + event.channel.send_message("Error: role #{role} does not exist.\nAvailable roles are: " + + $config['selfRoles'].keys.join(', ')) + end end end diff --git a/main.rb b/main.rb index 24bdd6e..2edc23c 100755 --- a/main.rb +++ b/main.rb @@ -34,7 +34,7 @@ $user_type = 'normal' $bot.command :sudo do |event, *args| - if event.author.roles.select { |role| role.id == $config['roles']['sudoersRole'] }.empty? + if event.author.roles.select { |role| role.id == $config['sudoersRole'] }.empty? event.channel.send_message("<@#{event.author.id}> is not in the sudoers file. This incident will be reported.") else run_command = args[0] From cfe0e6e92b56adfac926c26d36d86e8c10a589af Mon Sep 17 00:00:00 2001 From: Lucio Delelis Date: Sun, 3 Dec 2017 01:28:15 -0300 Subject: [PATCH 4/5] Turns out Rubocop also lints the Gemfile Thanks emacs for NOT warning me --- Gemfile | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Gemfile b/Gemfile index ef2ee4e..3e35940 100644 --- a/Gemfile +++ b/Gemfile @@ -1,8 +1,8 @@ -source "https://rubygems.org" do - gem 'fullwidth' - gem 'discordrb' - gem 'figlet' - gem 'cowsay' - gem 'fortune_gem' - gem 'pry' +source 'https://rubygems.org' do + gem 'cowsay' + gem 'discordrb' + gem 'figlet' + gem 'fortune_gem' + gem 'fullwidth' + gem 'pry' end From 128e8812155616cd443239fd4f6083b540685973 Mon Sep 17 00:00:00 2001 From: Lucio Delelis Date: Sun, 3 Dec 2017 01:44:32 -0300 Subject: [PATCH 5/5] This should fix piping behavior without breaking sudo Moved the break clause higher to avoid garbage returns when piping a sudo command --- lib/admin.rb | 4 ++-- lib/fun.rb | 22 +++++++++++----------- lib/utilities.rb | 20 ++++++++------------ main.rb | 4 ++-- 4 files changed, 23 insertions(+), 27 deletions(-) diff --git a/lib/admin.rb b/lib/admin.rb index 4053ea0..3eb5549 100644 --- a/lib/admin.rb +++ b/lib/admin.rb @@ -12,7 +12,7 @@ module Admin to_delete = event.channel.history(args.empty? ? 100 : args[0].to_i + 1) event.channel.delete_messages(to_delete) else - event.channel.send_message('Permission denied.') + 'Permission denied.' end end @@ -32,7 +32,7 @@ module Admin Process.detach(time_out) return else - event.channel.send_message('Permission denied.') + 'Permission denied.' end end end diff --git a/lib/fun.rb b/lib/fun.rb index 49fb1b5..f7ae44d 100644 --- a/lib/fun.rb +++ b/lib/fun.rb @@ -5,8 +5,8 @@ module Fun command(:aesthic, description: 'Makes a message A E S T H E T I C', usage: '[text to convert]', - min_args: 1) do |event, *args| - event.channel.send_message(args.join(' ').to_fullwidth) + min_args: 1) do |_event, *args| + args.join(' ').to_fullwidth end command(:step, @@ -14,26 +14,26 @@ module Fun usage: '[text]', min_args: 1) do |event, *args| args.to_a.delete_at(0) if args.include?('on') - event.channel.send_message("<@#{event.author.id}> steps on #{args.join(' ')}") + "<@#{event.author.id}> steps on #{args.join(' ')}" end command(:slap, description: 'Hit someone or something', usage: '[text]') do |event, *args| - event.channel.send_message("<@#{event.author.id}> slaps #{args.join(' ')} around a bit with a large trout") + "<@#{event.author.id}> slaps #{args.join(' ')} around a bit with a large trout" end command(:figlet, description: 'Turns a message into big ASCII art letters', usage: '[text]', - min_args: 1) do |event, *args| - event.channel.send_message('```' + $figlet[args.join('')] + '```') + min_args: 1) do |_event, *args| + '```' + $figlet[args.join('')] + '```' end command(:cowsay, description: 'Wraps a message with an ASCII art cow', usage: '[text]', - min_args: 1) do |event, *args| + min_args: 1) do |_event, *args| input_text = args.join(' ').gsub('```', '') rendered_text = Cowsay.say(input_text, 'cow') chunked_text = '' @@ -47,7 +47,7 @@ module Fun chunked_text << "```\n" + rendered_text.slice!(0..last_index) + "\n```" \ + ' ' * last_line.length + "\n" end - event.channel.send_message(chunked_text) + chunked_text end command(:me, @@ -55,11 +55,11 @@ module Fun usage: '[text]', min_args: 1) do |event, *args| event.channel.delete_message(event.channel.history(1)[0]) - event.channel.send_message("<@#{event.user.id}> *#{args.join(' ')}*") + "<@#{event.user.id}> *#{args.join(' ')}*" end command(:fortune, - description: 'Outputs a random fortune / divination / bad joke') do |event| - event.channel.send_message('```' + FortuneGem.give_fortune + '```') + description: 'Outputs a random fortune / divination / bad joke') do |_event| + '```' + FortuneGem.give_fortune + '```' end end diff --git a/lib/utilities.rb b/lib/utilities.rb index 05e49bf..899c015 100644 --- a/lib/utilities.rb +++ b/lib/utilities.rb @@ -33,23 +33,21 @@ module Utilities command(:echo, description: 'Echoes text.', usage: '[text to echo]', - min_args: 1) do |event, *args| - event.channel.send_message(args.join(' ')) + min_args: 1) do |_event, *args| + args.join(' ') end command(:lusers, description: 'Prints the amount of lusers currently online.', usage: '!lusers') do |event| - event.channel.send_message('Amount of lusers currently ' \ - "#{$config['lusersList'].sample}:" \ - "#{event.server.online_users(include_idle: true).length}") + "Amount of lusers currently #{$config['lusersList'].sample}:" \ + "#{event.server.online_users(include_idle: true).length}" end command(:checksudo, description: "Prints if you're a sudoer", usage: '!checksudo') do |event| - event.channel.send_message('You are a ' \ - "#{event.user.roles.include?($config['sudoersRole']) ? 'sudoer' : 'regular user'}.") + "You are a #{event.user.roles.include?($config['sudoersRole']) ? 'sudoer' : 'regular user'}." end command(:getrole, @@ -59,14 +57,12 @@ module Utilities role = args.join('') if $config['selfRoles'].key?(role) if event.author.role?(role) - event.channel.send_message('This user has already assigned that role to himself!') - return + 'This user has already assigned that role to himself!' end event.author.add_role($config['selfRoles'][role]) - event.channel.send_message("<@#{event.author.id}> was assigned the role #{role}!") + "<@#{event.author.id}> was assigned the role #{role}!" else - event.channel.send_message("Error: role #{role} does not exist.\nAvailable roles are: " + - $config['selfRoles'].keys.join(', ')) + "Error: role #{role} does not exist.\nAvailable roles are: $config['selfRoles'].keys.join(', ')" end end end diff --git a/main.rb b/main.rb index 2edc23c..154a40b 100755 --- a/main.rb +++ b/main.rb @@ -42,8 +42,8 @@ $user_type = 'sudoer' $bot.execute_command(run_command.to_sym, event, args) $user_type = 'normal' + break # Avoids garbage messages end - break # Avoids garbage messages end $pasta.keys.each do |pasta| # Slightly improved @@ -63,7 +63,7 @@ end end end - event.channel.send_message(message) + message end end end