From ed09327eac899b9d5a1f782616747ca13c4806b1 Mon Sep 17 00:00:00 2001 From: David Vazgenovich Shakaryan Date: Sat, 19 Apr 2014 20:22:05 -0700 Subject: Move protocol functionality to separate file. --- dinobot.rb | 76 ++++++++++++++++++++++--------------------------------- irc.rb | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 115 insertions(+), 46 deletions(-) create mode 100644 irc.rb diff --git a/dinobot.rb b/dinobot.rb index ce08b7c..ffb38f3 100644 --- a/dinobot.rb +++ b/dinobot.rb @@ -1,6 +1,7 @@ -require 'socket' require 'timeout' +require_relative 'irc' + module Dinobot class Bot attr_accessor :trigger @@ -14,73 +15,42 @@ module Dinobot @trigger = '!' - @socket = nil + @irc = Dinobot::IRC.new(@server, @port, @nick, @pass) @modules = Hash.new @channels = Array.new instance_eval(&block) if block_given? end - def connect - log :info, "Connecting to #{@server}:#{@port}." - @socket = TCPSocket.new(@server, @port) - - out "PASS #{@pass}" if @pass - out "NICK #{@nick}" - out "USER #{@nick} 0 * :#{@nick}" + def run + @irc.connect unless @irc.connected? @channels.each do |channel| - join channel + @irc.join channel end - end - def connected? - !(@socket.nil? || @socket.closed?) - end - - def run - connect unless connected? - - while str = @socket.gets.chomp - log :in, str.inspect - - Thread.new do - begin - Timeout.timeout(30) do - parse_line(str) - end - rescue => e - log :error, "Error parsing line. (#{e})" - log :indent, *e.backtrace - end - end + while str = @irc.gets + parse_in_new_thread(str) end - @socket.close + @irc.disconnect log :info, 'Disconnected.' end - def out(str) - return unless connected? - - log :out, str.inspect - @socket.puts str - end - def say(channel, message) - out "PRIVMSG #{channel} :#{message}" + @irc.privmsg(channel, message) end def join(channel) @channels << channel unless @channels.include?(channel) - out "JOIN #{channel}" + @irc.join(channel) if @irc.connected? end def part(channel) @channels.delete(channel) - out "PART #{channel}" + @irc.part(channel) end def load_module(mod) @@ -139,17 +109,31 @@ module Dinobot private + def parse_in_new_thread(str) + Thread.new do + begin + Timeout.timeout(30) do + parse_line(str.chomp) + end + rescue => e + log :error, "Error parsing line. (#{e})" + log :indent, *e.backtrace + end + end + end + def parse_line(str) - out str.sub('PING', 'PONG') if str =~ /^PING / + @irc.pong str.sub(/\APING /, 'PONG') if str =~ /\APING / if str =~ /(\S+) PRIVMSG (\S+) :(.*)/ user, channel, message = str.scan(/(\S+) PRIVMSG (\S+) :(.*)/).first return unless message.sub!(/^#{Regexp.escape(@trigger)}/, '') - methods = exec_command(user, channel, message) - ensure_valid_methods(methods) - run_methods(methods) + if methods = exec_command(user, channel, message) + ensure_valid_methods(methods) + run_methods(methods) + end end end diff --git a/irc.rb b/irc.rb new file mode 100644 index 0000000..835694e --- /dev/null +++ b/irc.rb @@ -0,0 +1,85 @@ +require 'socket' + +module Dinobot + class IRC + def initialize(server, port, nick, pass=nil) + @server = server + @port = port + @nick = nick + @pass = pass + + @socket = nil + end + + def connect + log :info, "Connecting to #{@server}:#{@port}." + + @socket = TCPSocket.new(@server, @port) + + puts "PASS #{@pass}" if @pass + puts "NICK #{@nick}" + puts "USER #{@nick} 0 * :#{@nick}" + end + + def disconnect + @socket.close + end + + def connected? + !(@socket.nil? || @socket.closed?) + end + + def gets + str = @socket.gets + + log :in, str.inspect + + str + end + + def puts(str) + log :out, str.inspect + + @socket.puts str + end + + def join(channel) + puts "JOIN #{channel}" + end + + def part(channel) + puts "PART #{channel}" + end + + def privmsg(channel, message) + puts "PRIVMSG #{channel} :#{message}" + end + + def pong(message) + puts "PONG #{message}" + end + + private + + def log(type, *lines) + str = lines.join("\n") + + case type + when :in + prefix = "\e[32m<<\e[0m " + when :out + prefix = "\e[36m>>\e[0m " + when :error + prefix = "\e[31m!!\e[0m " + when :info + prefix = "\e[33m==\e[0m " + when :indent + prefix = ' ' + else + raise "unknown type specified -- #{type}" + end + + Kernel.puts str.gsub(/^/, prefix) + end + end +end -- cgit v1.2.3-70-g09d2