08-05-2010, 11:40 PM
Code:
#!ruby
#main.rb
require 'socket'
require 'nandlib'
load 'irc.rb'
$irc = IRC.new 'irc.lolipower.org', 6667, "KawaiiBot"
$irc.owner = 'nand'
load 'events.rb'
fork do
loop do
catch :disconnected do
if $irc.connect
$irc.handle
else
puts "Failed to connect.."
end
end
puts "Disconnected!"
print "Reconnecting in "
(5).downto(1) {|n| puts n; sleep 1 }
end
end
while gets
load 'irc.rb'
load 'events.rb'
puts "Reloaded."
end
#!ruby
#irc.rb
class CatchCall
attr_accessor :catch, :block
def initialize(catch, block)
@catch = catch
@block = block
end
end
class IRC
attr_reader :name
attr :server, :port, :sock
attr_accessor :owner
def initialize(host, port, name)
@host = host
@port = port
@name = name
@buffer = ""
@events = []
@catchcalls = []
end
def connect
begin
puts "Connecting to #{@host}:#{@port}..."
@sock = TCPSocket.open(@host, @port)
puts "Connected."
# Time to register
sendraw "USER #{((@name + ' ') * 3).chop} :#{@name}"
sendraw "NICK #{@name}"
return true
rescue Exception => exc
puts "Failed to connect!"
return false
end
end
def send(t, m)
sendraw "PRIVMSG #{t} :#{m}"
end
def join(c)
sendraw "JOIN #{c}"
end
def part(c)
sendraw "PART #{c}"
end
def notice(t, m)
sendraw "NOTICE #{t} :#{m}"
end
def sendraw(s)
raise "Message too long" if s.length > 510
s << "\r\n" unless s =~ /\r\n$/
@sock.write s
end
def recvraw
str = @sock.gets
throw :disconnected if str.nil?
unless @buffer.empty?
str = @buffer + str
@buffer = ''
end
if str =~ /\r?\n([^\r\n]+)$/
@buffer = $1
str = $`
end
if block_given? then str.split(/\r?\n/).each {|l| yield l}
else return str.split(/\r?\n/) end
end
def handle
begin
while recvraw {|s| process s }; end
rescue Exception => exc
puts "Exception: " << exc.to_s
print exc.backtrace.join("\n"), "\n"
notice @owner, "Exception: " << exc.to_s if @owner
notice @owner, "Location: " << exc.backtrace[0].to_s if @owner
retry
end
end
def process(str)
raise "malformed packet: \n" << str unless str =~ /^(:[^ ]+ )?([^ ]+)( .*)?$/
prefix, command, postfix = $1, $2, $3
prefix.chip!.chop! if prefix
command.downcase!
postfix.chip! if postfix
args = postfix ? postfix.split(/ /) : []
if postfix =~ /:/
found = nil
tot = args.deep_dup.inject('') {|n, val|
(found = val.dup) && val.chip! if !found && val[0] == ':'
found ? n << (n.empty? ? '' : ' ') << val : n}
args[args.index(found)..args.length] = tot if found
end
@events.each do |cc|
if cc.catch === command
if Regexp === cc.catch
reg = $~.dup
cc.block.call(prefix, command, args, reg)
else
cc.block.call(prefix, command, args)
end
end
end
if command == "privmsg" || command == "notice"
target = args[0]
message = args[1]
sender = prefix
target = nick(sender) if isme? target
@catchcalls.each do |cc|
if cc.catch === message
if Regexp === cc.catch
reg = $~.dup
cc.block.call(sender, target, message, reg)
else
cc.block.call(sender, target, message)
end
end
end
end
end
def hook(*match, &block)
match.each do |m|
m = m.to_s if Integer === m || Symbol === m
m.downcase! if String === m
@events << CatchCall.new(m, block)
end
end
def catch(*match, &block)
match.each do |m|
if String === m || Regexp === m then
@catchcalls << CatchCall.new(m, block)
else
raise ArgumentError, "Keys must be of type String or Regexp", caller
end
end
end
def unhook_all
@events = []
end
def uncatch_all
@catchcalls = []
end
def myname
@name
end
def isme?(s)
@name == nick(s)
end
end
def nick(host)
$1 if host =~/([^!]+)(!.*)?/
end
#!ruby
#events.rb
$irc.unhook_all
$irc.uncatch_all
# Reloading method
$irc.catch(/^!reload$/) do |s, t, m, r|
if s =~ /.?nand!.*@nand.*/
puts "Reloading..."
load 'irc.rb'
load 'events.rb'
$irc.notice nick(s), "Reloaded."
end
end
$irc.hook(:ping) {|s, c, a|
$irc.sendraw (a.empty? ? "PONG" : "PONG #{a[0]}")
}
$irc.hook(376) {|s, c, a|
$irc.join "#Aaron"
$irc.join "#r0b0tz"
}
$irc.hook(:kick) {|s, c, a|
$irc.join a[0] if $irc.isme? a[1]
}
$irc.catch(/^!ping$/, /^Ping!$/) {|s, t, m, r|
$irc.send t, "Pong!"
}
$irc.catch(/^!eval (.*)/) {|s, t, m, r|
if s =~ /nand!.*@nand.*/
begin
$irc.send t, "=> " << eval(r[1]).inspect
rescue Exception => exc
$irc.send t, "Exception: " << exc.to_s
end
end
}
$irc.catch(/^!join (#[^ ]+)$/) {|s, t, m, r|
$irc.join r[1]
}
$irc.catch(/^!part( #[^ ]+)?$/) {|s, t, m, r|
$irc.part (r[1].chip ? r[1] : t) unless t == s
}
$irc.catch(/^\001VERSION\001$/i) {|s, t, m, r|
$irc.notice t, "\1VERSION nandbot v0.whatever (Ruby ver #{RUBY_VERSION})\1"
}
$irc.catch(/^\001PING ([^ ]+)\001$/i) {|s, t, m, r|
$irc.notice t, "\1PING #{r[1]}\1"
}
$irc.hook(:privmsg) {|s, c, a|
print a[0], ' <', nick(s), '> ', a[1], "\n"
}
Yep.
another irc bot.
^