#!/usr/bin/env ruby require 'socket' require 'open3' module IRC class User attr_accessor :s def initialize addr, port, nick @hooks = [] @s = TCPSocket.open addr, port.to_s s.puts "USER #{nick} fakehost whatevenisaservername :beep boop" s.puts "NICK #{nick}" hook do |m| next unless m.cmd == 'PING' raw "PING #{nick}" end end def raw msg @s.puts msg end def join chan raw "JOIN #{chan}" end def privmsg target, msg raw "PRIVMSG #{target} :#{msg}" end def hook &h @hooks << h end def loop while line = s.gets msg = Message.new line @hooks.each{|h| h.call(msg)} end end end class Message attr_accessor :prefix, :cmd, :args, :raw # TODO custom constructor def initialize msg msg = msg.delete_suffix "\r\n" @raw = msg @prefix = nil @prefix, msg = msg[1..].split(' ', 2) if msg[0] == ':' @cmd, msg = msg.split(' ', 2) @args = [] while msg and not msg.empty? if msg[0] == ':' @args << msg[1..] break end s, msg = msg.split(' ', 2) @args << s end end end end puts "starting" i = IRC::User.new 'localhost', 6667, 'our' i.join '#tildetown' i.join '#bots' i.hook do |msg| next unless msg.cmd == 'PRIVMSG' target, content = msg.args next unless content.delete_prefix! 'our/' cmd, args = content.split(' ', 2) cmd = '/town/our/' + cmd args ||= '' next unless File.exists? cmd if not File.executable? cmd i.privmsg target, "#{cmd} isn't executable. try chmod +x" next end begin # child = IO.popen [cmd, args, msg.prefix, target] # out = child.gets # child.close Open3.popen2e(cmd, args, msg.prefix, target) {|_, stdout, _| out = stdout.gets i.privmsg target, out if out } rescue Exception => e i.privmsg target, "[our.rb] #{e.to_s}" end next true end i.loop