Commit b403ce19bf250a85ef8d1866375413736c19a8a7
- Diff rendering mode:
- inline
- side by side
INSTALL
(3 / 0)
|   | |||
| 1 | |||
| 2 | rake gem | ||
| 3 | gem install pkg/rif-0.1.gem |
README
(24 / 0)
|   | |||
| 1 | |||
| 2 | == Install | ||
| 3 | |||
| 4 | gem install rif | ||
| 5 | |||
| 6 | |||
| 7 | == Example | ||
| 8 | |||
| 9 | require 'rubygems' | ||
| 10 | gem 'rif' | ||
| 11 | |||
| 12 | require 'rif/bot' | ||
| 13 | |||
| 14 | class Bot < RIF::Bot | ||
| 15 | def on_endofmotd(event) | ||
| 16 | join("#flood") | ||
| 17 | end | ||
| 18 | def do_foo(event, args) | ||
| 19 | send_message(event.from, "bar") | ||
| 20 | end | ||
| 21 | end | ||
| 22 | |||
| 23 | bot = Bot.new("bot", "irc.freenode.net", 6667, "RIF Bot") | ||
| 24 | bot.connect |
examples/bot.rb
(2 / 2)
|   | |||
| 2 | 2 | ||
| 3 | 3 | $: << File.join(File.dirname(__FILE__), "../lib/") | |
| 4 | 4 | ||
| 5 | require 'irc/bot' | ||
| 5 | require 'rif/bot' | ||
| 6 | 6 | ||
| 7 | class MyBot < IRC::Bot | ||
| 7 | class MyBot < RIF::Bot | ||
| 8 | 8 | def initialize(nick, server, port, name) | |
| 9 | 9 | super | |
| 10 | 10 | end |
lib/irc/bot.rb
(0 / 34)
|   | |||
| 1 | |||
| 2 | require 'irc/botbase' | ||
| 3 | |||
| 4 | module IRC | ||
| 5 | |||
| 6 | class Bot < BotBase | ||
| 7 | attr_accessor :operator | ||
| 8 | def initialize(nick, server, port, realname='RBot') | ||
| 9 | super | ||
| 10 | |||
| 11 | @operator = "%" | ||
| 12 | end | ||
| 13 | |||
| 14 | def on_privmsg(event) | ||
| 15 | if event.message =~ /^#{@operator}(\w+)(\s|.+)*/ | ||
| 16 | command = $1 | ||
| 17 | args = $2.to_s.split(/\s+/) | ||
| 18 | method = "do_#{command}".to_sym | ||
| 19 | |||
| 20 | if respond_to?(method) | ||
| 21 | if respond_to?(method) | ||
| 22 | __send__(method, event, args) | ||
| 23 | return true | ||
| 24 | end | ||
| 25 | else | ||
| 26 | $stderr.puts "Invalid action: #{command} from #{event.from} in #{event.channel}" | ||
| 27 | end | ||
| 28 | end | ||
| 29 | |||
| 30 | on_message(event) if respond_to?(:on_message) | ||
| 31 | end | ||
| 32 | end | ||
| 33 | |||
| 34 | end |
lib/irc/botbase.rb
(0 / 178)
|   | |||
| 1 | |||
| 2 | require 'socket' | ||
| 3 | require 'irc/connection' | ||
| 4 | require 'irc/event' | ||
| 5 | require 'irc/channel' | ||
| 6 | require 'irc/user' | ||
| 7 | require 'irc/util' | ||
| 8 | |||
| 9 | module IRC | ||
| 10 | |||
| 11 | # Class IRC is a master class that handles connection to the irc | ||
| 12 | # server and pasring of IRC events, through the IRC::Event class. | ||
| 13 | class BotBase | ||
| 14 | attr_reader :nick, :server, :port | ||
| 15 | |||
| 16 | @channels = nil | ||
| 17 | # Create a new IRC Object instance | ||
| 18 | def initialize( nick, server, port, realname='RBot') | ||
| 19 | @nick = nick | ||
| 20 | @server = server | ||
| 21 | @port = port | ||
| 22 | @realname = realname | ||
| 23 | @channels = Array.new(0) | ||
| 24 | # Some good default Event handlers. These can and will be overridden by users. | ||
| 25 | # Thses make changes on the IRCbot object. So they need to be here. | ||
| 26 | |||
| 27 | # Topic events can come on two tags, so we create on proc to handle them. | ||
| 28 | |||
| 29 | topic_proc = Proc.new { |event| | ||
| 30 | self.channels.each { |chan| | ||
| 31 | if chan == event.channel | ||
| 32 | chan.topic = event.message | ||
| 33 | end | ||
| 34 | } | ||
| 35 | } | ||
| 36 | |||
| 37 | IRC::Event.add_handler('332', topic_proc) | ||
| 38 | IRC::Event.add_handler('topic', topic_proc) | ||
| 39 | |||
| 40 | unhandle_proc = Proc.new { |event| | ||
| 41 | method_id = "on_#{event.type}".to_sym | ||
| 42 | if respond_to?(method_id) | ||
| 43 | __send__(method_id, event) | ||
| 44 | elsif $DEBUG | ||
| 45 | $stderr.puts "=> Undefined method #{method_id}" | ||
| 46 | end | ||
| 47 | } | ||
| 48 | |||
| 49 | IRC::Event.add_handler("unhandled", unhandle_proc) | ||
| 50 | end | ||
| 51 | |||
| 52 | # Join a channel, adding it to the list of joined channels | ||
| 53 | def add_channel channel | ||
| 54 | join(channel) | ||
| 55 | self | ||
| 56 | end | ||
| 57 | |||
| 58 | # Returns a list of channels joined | ||
| 59 | def channels | ||
| 60 | @channels | ||
| 61 | end | ||
| 62 | |||
| 63 | # Open a connection to the server using the IRC Connect | ||
| 64 | # method. Events yielded from the IRC::Connection handler are | ||
| 65 | # processed and then control is returned to IRC::Connection | ||
| 66 | def connect | ||
| 67 | quithandler = lambda { send_quit(); IRC::Connection.quit; exit 0 } | ||
| 68 | trap("INT", quithandler) | ||
| 69 | trap("TERM", quithandler) | ||
| 70 | |||
| 71 | IRC::Connection.handle_connection(@server, @port, @nick, @realname) do | ||
| 72 | # Log in information moved to IRC::Connection | ||
| 73 | @threads = [] | ||
| 74 | IRC::Connection.main do |event| | ||
| 75 | if event.kind_of?(Array) | ||
| 76 | event.each {|event| | ||
| 77 | thread_event(event) | ||
| 78 | } | ||
| 79 | else | ||
| 80 | thread_event(event) | ||
| 81 | end | ||
| 82 | end | ||
| 83 | @threads.each {|thr| thr.join } | ||
| 84 | end | ||
| 85 | end | ||
| 86 | alias start connect | ||
| 87 | |||
| 88 | # Joins a channel on a server. | ||
| 89 | def join(*channels) | ||
| 90 | channels.each { |channel| | ||
| 91 | if (IRC::Connection.send_to_server("JOIN #{channel}")) | ||
| 92 | @channels.push(IRC::Channel.new(channel)); | ||
| 93 | end | ||
| 94 | } | ||
| 95 | end | ||
| 96 | |||
| 97 | # Leaves a channel on a server | ||
| 98 | def part(channel) | ||
| 99 | if (IRC::Connection.send_to_server("PART #{channel}")) | ||
| 100 | @channels.delete_if {|chan| chan.name == channel } | ||
| 101 | end | ||
| 102 | end | ||
| 103 | |||
| 104 | # kicks a user from a channel (does not check for operator privledge) | ||
| 105 | def kick(channel, user, message) | ||
| 106 | IRC::Connection.send_to_server("KICK #{channel} #{user} :#{message || user || 'kicked'}") | ||
| 107 | end | ||
| 108 | |||
| 109 | # sets the topic of the given channel | ||
| 110 | def set_topic(channel, topic) | ||
| 111 | IRC::Connection.send_to_server("TOPIC #{channel} :#{topic}"); | ||
| 112 | end | ||
| 113 | |||
| 114 | # Sends a private message, or channel message | ||
| 115 | def send_message(to, message) | ||
| 116 | IRC::Connection.send_to_server("privmsg #{to} :#{message}"); | ||
| 117 | end | ||
| 118 | |||
| 119 | # Sends a notice | ||
| 120 | def send_notice(to, message) | ||
| 121 | IRC::Connection.send_to_server("NOTICE #{to} :#{message}"); | ||
| 122 | end | ||
| 123 | |||
| 124 | # performs an action | ||
| 125 | def send_action(to, action) | ||
| 126 | send_ctcp(to, 'ACTION', action); | ||
| 127 | end | ||
| 128 | |||
| 129 | # send CTCP | ||
| 130 | def send_ctcp(to, type, message) | ||
| 131 | IRC::Connection.send_to_server("privmsg #{to} :\001#{type} #{message}"); | ||
| 132 | end | ||
| 133 | |||
| 134 | # Quits the IRC Server | ||
| 135 | def send_quit | ||
| 136 | IRC::Connection.send_to_server("QUIT : Quit ordered by user") | ||
| 137 | end | ||
| 138 | |||
| 139 | # Ops selected user. | ||
| 140 | def op(channel, user) | ||
| 141 | IRC::Connection.send_to_server("MODE #{channel} +o #{user}") | ||
| 142 | end | ||
| 143 | |||
| 144 | # Changes the current nickname | ||
| 145 | def ch_nick(nick) | ||
| 146 | IRC::Connection.send_to_server("NICK #{nick}") | ||
| 147 | @nick = nick | ||
| 148 | end | ||
| 149 | |||
| 150 | # Removes operator status from a user | ||
| 151 | def deop(channel, user) | ||
| 152 | IRC::Connection.send_to_server("MODE #{channel} -o #{user}") | ||
| 153 | end | ||
| 154 | |||
| 155 | # Changes target users mode | ||
| 156 | def mode(channel, user, mode) | ||
| 157 | IRC::Connection.send_to_server("MODE #{channel} #{mode} #{user}") | ||
| 158 | end | ||
| 159 | |||
| 160 | # Retrievs user information from the server | ||
| 161 | def get_user_info(user) | ||
| 162 | IRC::Connection.send_to_server("WHO #{user}") | ||
| 163 | end | ||
| 164 | private | ||
| 165 | def thread_event(event) | ||
| 166 | @threads << Thread.new(event) { |localevent| | ||
| 167 | begin | ||
| 168 | localevent.process | ||
| 169 | rescue => e | ||
| 170 | puts "Error: #{e.message}" | ||
| 171 | puts e.backtrace.map { |e| " from #{e}\n" } | ||
| 172 | exit -1 | ||
| 173 | end | ||
| 174 | } | ||
| 175 | end | ||
| 176 | end | ||
| 177 | |||
| 178 | end |
lib/irc/channel.rb
(0 / 38)
|   | |||
| 1 | require "irc/user" | ||
| 2 | |||
| 3 | module IRC | ||
| 4 | |||
| 5 | # Represents an IRC Channel | ||
| 6 | class Channel | ||
| 7 | def initialize(name) | ||
| 8 | @name = name | ||
| 9 | @users = Array.new(0) | ||
| 10 | end | ||
| 11 | attr_reader :name | ||
| 12 | |||
| 13 | # set the topic on this channel | ||
| 14 | def topic=(topic) | ||
| 15 | @topic = topic | ||
| 16 | end | ||
| 17 | |||
| 18 | # get the topic on this channel | ||
| 19 | def topic | ||
| 20 | if @topic | ||
| 21 | return @topic | ||
| 22 | end | ||
| 23 | return "No Topic set" | ||
| 24 | end | ||
| 25 | |||
| 26 | # add a user to this channel's userlist | ||
| 27 | def add_user(username) | ||
| 28 | @users.push(IRC::User.create_user(username)) | ||
| 29 | end | ||
| 30 | |||
| 31 | # returns the current user list for this channel | ||
| 32 | def users | ||
| 33 | @users | ||
| 34 | end | ||
| 35 | end | ||
| 36 | |||
| 37 | |||
| 38 | end |
lib/irc/connection.rb
(0 / 124)
|   | |||
| 1 | |||
| 2 | |||
| 3 | |||
| 4 | module IRC | ||
| 5 | |||
| 6 | # Handles connection to IRC Server | ||
| 7 | class Connection | ||
| 8 | @@quit = 0 | ||
| 9 | @@readsockets = Array.new(0) | ||
| 10 | @@output_buffer = Array.new(0) | ||
| 11 | @@events = Hash.new() | ||
| 12 | @@last_send = Time.now.to_f | ||
| 13 | @@message_delay = 0.2 # Default delay to 1 fifth of a second. | ||
| 14 | # Creates a socket connection and then yields. | ||
| 15 | def self.handle_connection(server, port, nick='ChangeMe', realname='MeToo' ) | ||
| 16 | @server = server; | ||
| 17 | @port = port | ||
| 18 | @nick = nick | ||
| 19 | @realname = realname | ||
| 20 | socket = create_tcp_socket(server, port) | ||
| 21 | add_IO_socket(socket) {|sock| | ||
| 22 | begin | ||
| 23 | IRC::Event.new(sock.readline.chomp) | ||
| 24 | rescue Errno::ECONNRESET | ||
| 25 | # Catches connection reset by peer, attempts to reconnect | ||
| 26 | # after sleeping for 10 second. | ||
| 27 | remove_IO_socket(sock) | ||
| 28 | sleep 10 | ||
| 29 | handle_connection(@server, @port, @nick, @realname) | ||
| 30 | end | ||
| 31 | } | ||
| 32 | send_to_server "NICK #{nick}" | ||
| 33 | send_to_server "USER #{nick} 8 * :#{realname}" | ||
| 34 | if block_given? | ||
| 35 | yield | ||
| 36 | @@socket.close | ||
| 37 | end | ||
| 38 | end | ||
| 39 | |||
| 40 | def self.create_tcp_socket(server, port) | ||
| 41 | @@socket = TCPsocket.open(server, port) | ||
| 42 | if block_given? | ||
| 43 | yield | ||
| 44 | @@socket.close | ||
| 45 | return | ||
| 46 | end | ||
| 47 | return @@socket | ||
| 48 | end | ||
| 49 | |||
| 50 | # Sends a line of text to the server | ||
| 51 | def self.send_to_server(line) | ||
| 52 | @@socket.write(line + "\n") | ||
| 53 | end | ||
| 54 | |||
| 55 | # Adds data an output buffer. This let's us keep a handle on how | ||
| 56 | # fast we send things. Yay. | ||
| 57 | def self.output_push(line) | ||
| 58 | @@output_buffer.push(line) | ||
| 59 | end | ||
| 60 | |||
| 61 | # This loop monitors all IO_Sockets self controls | ||
| 62 | # (including the IRC socket) and yields events to the IO_Sockets | ||
| 63 | # event handler. | ||
| 64 | def self.main | ||
| 65 | while(@@quit == 0) | ||
| 66 | do_one_loop { |event| | ||
| 67 | yield event | ||
| 68 | } | ||
| 69 | end | ||
| 70 | end | ||
| 71 | |||
| 72 | # Makes one single loop pass, checking all sockets for data to read, | ||
| 73 | # and yields the data to the sockets event handler. | ||
| 74 | def self.do_one_loop | ||
| 75 | read_sockets = select(@@readsockets, nil, nil, 0.1); | ||
| 76 | if !read_sockets.nil? | ||
| 77 | read_sockets[0].each {|sock| | ||
| 78 | if sock.eof? && sock == @@socket | ||
| 79 | p "Detected Socket Close" | ||
| 80 | remove_IO_socket(sock) | ||
| 81 | sleep 10 | ||
| 82 | handle_connection(@server, @port, @nick, @realname) | ||
| 83 | else | ||
| 84 | yield @@events[sock.to_i].call(sock) | ||
| 85 | end | ||
| 86 | } | ||
| 87 | end | ||
| 88 | if @@output_buffer.length > 0 | ||
| 89 | timer = Time.now.to_f | ||
| 90 | if (timer > @@last_send + @@message_delay) | ||
| 91 | message = @@output_buffer.shift(); | ||
| 92 | if !message.nil? | ||
| 93 | self.send_to_server(message); | ||
| 94 | @@last_send = timer | ||
| 95 | end | ||
| 96 | end | ||
| 97 | end | ||
| 98 | end | ||
| 99 | |||
| 100 | # Ends connection to the irc server | ||
| 101 | def self.quit | ||
| 102 | @@quit = 1 | ||
| 103 | end | ||
| 104 | def self.delay=(delay) | ||
| 105 | @@message_delay = delay.to_f | ||
| 106 | end | ||
| 107 | # Retrieves user info from the server | ||
| 108 | def self.get_user_info(user) | ||
| 109 | self.send_to_server("WHOIS #{user}") | ||
| 110 | end | ||
| 111 | |||
| 112 | # Adds a new socket to the list of sockets to monitor for new data. | ||
| 113 | def self.add_IO_socket(socket, &event_generator) | ||
| 114 | @@readsockets.push(socket) | ||
| 115 | @@events[socket.to_i] = event_generator | ||
| 116 | end | ||
| 117 | |||
| 118 | def self.remove_IO_socket(sock) | ||
| 119 | sock.close | ||
| 120 | @@readsockets.delete_if {|item| item == sock } | ||
| 121 | end | ||
| 122 | end | ||
| 123 | |||
| 124 | end |
lib/irc/event.rb
(0 / 119)
|   | |||
| 1 | require 'yaml' | ||
| 2 | |||
| 3 | module IRC | ||
| 4 | |||
| 5 | # This is a lookup class for IRC event name mapping | ||
| 6 | class EventLookup | ||
| 7 | @@lookup = YAML.load_file("#{File.dirname(__FILE__)}/eventmap.yml") | ||
| 8 | |||
| 9 | # returns the event name, given a number | ||
| 10 | def EventLookup::find_by_number(num) | ||
| 11 | return @@lookup[num.to_i] | ||
| 12 | end | ||
| 13 | end | ||
| 14 | |||
| 15 | |||
| 16 | # Handles an IRC generated event. | ||
| 17 | # Handlers are for the IRC framework to use | ||
| 18 | # Callbacks are for users to add. | ||
| 19 | # Both handlers and callbacks can be called for the same event. | ||
| 20 | class Event | ||
| 21 | @@handlers = { 'ping' => lambda {|event| IRC::Connection.send_to_server("PONG #{event.message}") } } | ||
| 22 | @@callbacks = Hash.new() | ||
| 23 | attr_reader :hostmask, :message, :type, :from, :channel, :target, :mode, :stats, :nick, :ident | ||
| 24 | def initialize (line) | ||
| 25 | puts "FROM SERVER: #{line}" if $DEBUG | ||
| 26 | |||
| 27 | line.sub!(/^:/, '') | ||
| 28 | mess_parts = line.split(':', 2); | ||
| 29 | # mess_parts[0] is server info | ||
| 30 | # mess_parts[1] is the message that was sent | ||
| 31 | @message = (mess_parts[1] ? mess_parts[1] : "" ) | ||
| 32 | @from = "" | ||
| 33 | @channel = "" | ||
| 34 | |||
| 35 | @stats = mess_parts[0].split(" ") | ||
| 36 | |||
| 37 | puts @stats.join(" | ") if $DEBUG | ||
| 38 | |||
| 39 | if @stats[0].match(/^PING/) | ||
| 40 | @type = 'ping' | ||
| 41 | elsif @message.match(/^(\x1(\w+))/) # ctcp | ||
| 42 | @from = @stats[0] | ||
| 43 | ctcp = $2.downcase | ||
| 44 | @type = "ctcp_#{ctcp}" | ||
| 45 | |||
| 46 | @message.gsub!($1, "") | ||
| 47 | elsif @stats[1] && @stats[1].match(/^\d+/) | ||
| 48 | @type = EventLookup::find_by_number(@stats[1]); | ||
| 49 | @channel = @stats[2] | ||
| 50 | else | ||
| 51 | @type = @stats[1].downcase if @stats[1] | ||
| 52 | end | ||
| 53 | |||
| 54 | if @type != 'ping' | ||
| 55 | @from = @stats[0] | ||
| 56 | @user = IRC::User.create_user(@from) | ||
| 57 | end | ||
| 58 | |||
| 59 | @hostmask = @from.split("@").last | ||
| 60 | @nick = @from.split("!").first | ||
| 61 | @ident = "" | ||
| 62 | |||
| 63 | if @from =~ /!(.+)@/ | ||
| 64 | @ident = $1 | ||
| 65 | end | ||
| 66 | |||
| 67 | @channel = @stats[2] if @stats[2] and @channel.empty? | ||
| 68 | @target = @stats[3] if @stats[3] | ||
| 69 | @mode = @stats[4] if @stats[4] | ||
| 70 | |||
| 71 | # Unfortunatly, not all messages are created equal. This is our | ||
| 72 | # special exceptions section | ||
| 73 | if @type == 'join' | ||
| 74 | @channel = @message | ||
| 75 | end | ||
| 76 | |||
| 77 | puts "EVENT: #{@type}" if $DEBUG | ||
| 78 | |||
| 79 | end | ||
| 80 | |||
| 81 | # Adds a callback for the specified irc message. | ||
| 82 | def self.add_callback(message_id, &callback) | ||
| 83 | @@callbacks[message_id] = callback | ||
| 84 | end | ||
| 85 | |||
| 86 | # Adds a handler to the handler function hash. | ||
| 87 | def self.add_handler(message_id, proc=nil, &handler) | ||
| 88 | if block_given? | ||
| 89 | @@handlers[message_id] = handler | ||
| 90 | elsif proc | ||
| 91 | @@handlers[message_id] = proc | ||
| 92 | end | ||
| 93 | end | ||
| 94 | |||
| 95 | # Process this event, preforming which ever handler and callback is specified | ||
| 96 | # for this event. | ||
| 97 | def process | ||
| 98 | handled = false | ||
| 99 | if @@handlers[@type] | ||
| 100 | @@handlers[@type].call(self) | ||
| 101 | handled = true | ||
| 102 | end | ||
| 103 | |||
| 104 | if @@callbacks[@type] | ||
| 105 | @@callbacks[@type].call(self) | ||
| 106 | handled = true | ||
| 107 | end | ||
| 108 | |||
| 109 | if not handled | ||
| 110 | if @@handlers["unhandled"] | ||
| 111 | @@handlers["unhandled"].call(self) | ||
| 112 | else | ||
| 113 | $stderr.puts "No handler for event type #@type in #{self.class}" if $DEBUG | ||
| 114 | end | ||
| 115 | end | ||
| 116 | end | ||
| 117 | end | ||
| 118 | |||
| 119 | end |
lib/irc/eventmap.yml
(0 / 247)
|   | |||
| 1 | # 001 ne 1 for the purpose of hash keying apparently. | ||
| 2 | 001 : welcome | ||
| 3 | 002 : yourhost | ||
| 4 | 003 : created | ||
| 5 | 004 : myinfo | ||
| 6 | 005 : map # Undernet Extension, Kajetan@Hinner.com, 17/11/98 | ||
| 7 | 006 : mapmore # Undernet Extension, Kajetan@Hinner.com, 17/11/98 | ||
| 8 | 007 : mapend # Undernet Extension, Kajetan@Hinner.com, 17/11/98 | ||
| 9 | 008 : snomask # Undernet Extension, Kajetan@Hinner.com, 17/11/98 | ||
| 10 | 009 : statmemtot # Undernet Extension, Kajetan@Hinner.com, 17/11/98 | ||
| 11 | 010 : statmem # Undernet Extension, Kajetan@Hinner.com, 17/11/98 | ||
| 12 | 200 : tracelink | ||
| 13 | 201 : traceconnecting | ||
| 14 | 202 : tracehandshake | ||
| 15 | 203 : traceunknown | ||
| 16 | 204 : traceoperator | ||
| 17 | 205 : traceuser | ||
| 18 | 206 : traceserver | ||
| 19 | 208 : tracenewtype | ||
| 20 | 209 : traceclass | ||
| 21 | 211 : statslinkinfo | ||
| 22 | 212 : statscommands | ||
| 23 | 213 : statscline | ||
| 24 | 214 : statsnline | ||
| 25 | 215 : statsiline | ||
| 26 | 216 : statskline | ||
| 27 | 217 : statsqline | ||
| 28 | 218 : statsyline | ||
| 29 | 219 : endofstats | ||
| 30 | 220 : statsbline # UnrealIrcd, Hendrik Frenzel | ||
| 31 | 221 : umodeis | ||
| 32 | 222 : sqline_nick # UnrealIrcd, Hendrik Frenzel | ||
| 33 | 223 : statsgline # UnrealIrcd, Hendrik Frenzel | ||
| 34 | 224 : statstline # UnrealIrcd, Hendrik Frenzel | ||
| 35 | 225 : statseline # UnrealIrcd, Hendrik Frenzel | ||
| 36 | 226 : statsnline # UnrealIrcd, Hendrik Frenzel | ||
| 37 | 227 : statsvline # UnrealIrcd, Hendrik Frenzel | ||
| 38 | 231 : serviceinfo | ||
| 39 | 232 : endofservices | ||
| 40 | 233 : service | ||
| 41 | 234 : servlist | ||
| 42 | 235 : servlistend | ||
| 43 | 241 : statslline | ||
| 44 | 242 : statsuptime | ||
| 45 | 243 : statsoline | ||
| 46 | 244 : statshline | ||
| 47 | 245 : statssline # Reserved, Kajetan@Hinner.com, 17/10/98 | ||
| 48 | 246 : statstline # Undernet Extension, Kajetan@Hinner.com, 17/10/98 | ||
| 49 | 247 : statsgline # Undernet Extension, Kajetan@Hinner.com, 17/10/98 | ||
| 50 | ### TODO: need numerics to be able to map to multiple strings | ||
| 51 | ### 247 : statsxline # UnrealIrcd, Hendrik Frenzel | ||
| 52 | 248 : statsuline # Undernet Extension, Kajetan@Hinner.com, 17/10/98 | ||
| 53 | 249 : statsdebug # Unspecific Extension, Kajetan@Hinner.com, 17/10/98 | ||
| 54 | 250 : luserconns # 1998-03-15 -- tkil | ||
| 55 | 251 : luserclient | ||
| 56 | 252 : luserop | ||
| 57 | 253 : luserunknown | ||
| 58 | 254 : luserchannels | ||
| 59 | 255 : luserme | ||
| 60 | 256 : adminme | ||
| 61 | 257 : adminloc1 | ||
| 62 | 258 : adminloc2 | ||
| 63 | 259 : adminemail | ||
| 64 | 261 : tracelog | ||
| 65 | 262 : endoftrace # 1997-11-24 -- archon | ||
| 66 | 265 : n_local # 1997-10-16 -- tkil | ||
| 67 | 266 : n_global # 1997-10-16 -- tkil | ||
| 68 | 271 : silelist # Undernet Extension, Kajetan@Hinner.com, 17/10/98 | ||
| 69 | 272 : endofsilelist # Undernet Extension, Kajetan@Hinner.com, 17/10/98 | ||
| 70 | 275 : statsdline # Undernet Extension, Kajetan@Hinner.com, 17/10/98 | ||
| 71 | 280 : glist # Undernet Extension, Kajetan@Hinner.com, 17/10/98 | ||
| 72 | 281 : endofglist # Undernet Extension, Kajetan@Hinner.com, 17/10/98 | ||
| 73 | 290 : helphdr # UnrealIrcd, Hendrik Frenzel | ||
| 74 | 291 : helpop # UnrealIrcd, Hendrik Frenzel | ||
| 75 | 292 : helptlr # UnrealIrcd, Hendrik Frenzel | ||
| 76 | 293 : helphlp # UnrealIrcd, Hendrik Frenzel | ||
| 77 | 294 : helpfwd # UnrealIrcd, Hendrik Frenzel | ||
| 78 | 295 : helpign # UnrealIrcd, Hendrik Frenzel | ||
| 79 | 300 : none | ||
| 80 | 301 : away | ||
| 81 | 302 : userhost | ||
| 82 | 303 : ison | ||
| 83 | 304 : rpl_text # Bahamut IRCD | ||
| 84 | 305 : unaway | ||
| 85 | 306 : nowaway | ||
| 86 | 307 : userip # Undernet Extension, Kajetan@Hinner.com, 17/10/98 | ||
| 87 | 308 : rulesstart # UnrealIrcd, Hendrik Frenzel | ||
| 88 | 309 : endofrules # UnrealIrcd, Hendrik Frenzel | ||
| 89 | 310 : whoishelp # (July01-01)Austnet Extension, found by Andypoo <andypoo@secret.com.au> | ||
| 90 | 311 : whoisuser | ||
| 91 | 312 : whoisserver | ||
| 92 | 313 : whoisoperator | ||
| 93 | 314 : whowasuser | ||
| 94 | 315 : endofwho | ||
| 95 | 316 : whoischanop | ||
| 96 | 317 : whoisidle | ||
| 97 | 318 : endofwhois | ||
| 98 | 319 : whoischannels | ||
| 99 | 320 : whoisvworld # (July01-01)Austnet Extension, found by Andypoo <andypoo@secret.com.au> | ||
| 100 | 321 : liststart | ||
| 101 | 322 : list | ||
| 102 | 323 : listend | ||
| 103 | 324 : channelmodeis | ||
| 104 | 329 : channelcreate # 1997-11-24 -- archon | ||
| 105 | 331 : notopic | ||
| 106 | 332 : topic | ||
| 107 | 333 : topicinfo # 1997-11-24 -- archon | ||
| 108 | 334 : listusage # Undernet Extension, Kajetan@Hinner.com, 17/10/98 | ||
| 109 | 335 : whoisbot # UnrealIrcd, Hendrik Frenzel | ||
| 110 | 341 : inviting | ||
| 111 | 342 : summoning | ||
| 112 | 346 : invitelist # UnrealIrcd, Hendrik Frenzel | ||
| 113 | 347 : endofinvitelist # UnrealIrcd, Hendrik Frenzel | ||
| 114 | 348 : exlist # UnrealIrcd, Hendrik Frenzel | ||
| 115 | 349 : endofexlist # UnrealIrcd, Hendrik Frenzel | ||
| 116 | 351 : version | ||
| 117 | 352 : whoreply | ||
| 118 | 353 : namreply | ||
| 119 | 354 : whospcrpl # Undernet Extension, Kajetan@Hinner.com, 17/10/98 | ||
| 120 | 361 : killdone | ||
| 121 | 362 : closing | ||
| 122 | 363 : closeend | ||
| 123 | 364 : links | ||
| 124 | 365 : endoflinks | ||
| 125 | 366 : endofnames | ||
| 126 | 367 : banlist | ||
| 127 | 368 : endofbanlist | ||
| 128 | 369 : endofwhowas | ||
| 129 | 371 : info | ||
| 130 | 372 : motd | ||
| 131 | 373 : infostart | ||
| 132 | 374 : endofinfo | ||
| 133 | 375 : motdstart | ||
| 134 | 376 : endofmotd | ||
| 135 | 377 : motd2 # 1997-10-16 -- tkil | ||
| 136 | 378 : austmotd # (July01-01)Austnet Extension, found by Andypoo <andypoo@secret.com.au> | ||
| 137 | 379 : whoismodes # UnrealIrcd, Hendrik Frenzel | ||
| 138 | 381 : youreoper | ||
| 139 | 382 : rehashing | ||
| 140 | 383 : youreservice # UnrealIrcd, Hendrik Frenzel | ||
| 141 | 384 : myportis | ||
| 142 | 385 : notoperanymore # Unspecific Extension, Kajetan@Hinner.com, 17/10/98 | ||
| 143 | 386 : qlist # UnrealIrcd, Hendrik Frenzel | ||
| 144 | 387 : endofqlist # UnrealIrcd, Hendrik Frenzel | ||
| 145 | 388 : alist # UnrealIrcd, Hendrik Frenzel | ||
| 146 | 389 : endofalist # UnrealIrcd, Hendrik Frenzel | ||
| 147 | 391 : time | ||
| 148 | 392 : usersstart | ||
| 149 | 393 : users | ||
| 150 | 394 : endofusers | ||
| 151 | 395 : nousers | ||
| 152 | 401 : nosuchnick | ||
| 153 | 402 : nosuchserver | ||
| 154 | 403 : nosuchchannel | ||
| 155 | 404 : cannotsendtochan | ||
| 156 | 405 : toomanychannels | ||
| 157 | 406 : wasnosuchnick | ||
| 158 | 407 : toomanytargets | ||
| 159 | 408 : nosuchservice # UnrealIrcd, Hendrik Frenzel | ||
| 160 | 409 : noorigin | ||
| 161 | 411 : norecipient | ||
| 162 | 412 : notexttosend | ||
| 163 | 413 : notoplevel | ||
| 164 | 414 : wildtoplevel | ||
| 165 | 416 : querytoolong # Undernet Extension, Kajetan@Hinner.com, 17/10/98 | ||
| 166 | 421 : unknowncommand | ||
| 167 | 422 : nomotd | ||
| 168 | 423 : noadmininfo | ||
| 169 | 424 : fileerror | ||
| 170 | 425 : noopermotd # UnrealIrcd, Hendrik Frenzel | ||
| 171 | 431 : nonicknamegiven | ||
| 172 | 432 : erroneusnickname # This iz how its speld in thee RFC. | ||
| 173 | 433 : nicknameinuse | ||
| 174 | 434 : norules # UnrealIrcd, Hendrik Frenzel | ||
| 175 | 435 : serviceconfused # UnrealIrcd, Hendrik Frenzel | ||
| 176 | 436 : nickcollision | ||
| 177 | 437 : bannickchange # Undernet Extension, Kajetan@Hinner.com, 17/10/98 | ||
| 178 | 438 : nicktoofast # Undernet Extension, Kajetan@Hinner.com, 17/10/98 | ||
| 179 | 439 : targettoofast # Undernet Extension, Kajetan@Hinner.com, 17/10/98 | ||
| 180 | 440 : servicesdown # Bahamut IRCD | ||
| 181 | 441 : usernotinchannel | ||
| 182 | 442 : notonchannel | ||
| 183 | 443 : useronchannel | ||
| 184 | 444 : nologin | ||
| 185 | 445 : summondisabled | ||
| 186 | 446 : usersdisabled | ||
| 187 | 447 : nonickchange # UnrealIrcd, Hendrik Frenzel | ||
| 188 | 451 : notregistered | ||
| 189 | 455 : hostilename # UnrealIrcd, Hendrik Frenzel | ||
| 190 | 459 : nohiding # UnrealIrcd, Hendrik Frenzel | ||
| 191 | 460 : notforhalfops # UnrealIrcd, Hendrik Frenzel | ||
| 192 | 461 : needmoreparams | ||
| 193 | 462 : alreadyregistered | ||
| 194 | 463 : nopermforhost | ||
| 195 | 464 : passwdmismatch | ||
| 196 | 465 : yourebannedcreep # I love this one... | ||
| 197 | 466 : youwillbebanned | ||
| 198 | 467 : keyset | ||
| 199 | 468 : invalidusername # Undernet Extension, Kajetan@Hinner.com, 17/10/98 | ||
| 200 | 469 : linkset # UnrealIrcd, Hendrik Frenzel | ||
| 201 | 470 : linkchannel # UnrealIrcd, Hendrik Frenzel | ||
| 202 | 471 : channelisfull | ||
| 203 | 472 : unknownmode | ||
| 204 | 473 : inviteonlychan | ||
| 205 | 474 : bannedfromchan | ||
| 206 | 475 : badchannelkey | ||
| 207 | 476 : badchanmask | ||
| 208 | 477 : needreggednick # Bahamut IRCD | ||
| 209 | 478 : banlistfull # Undernet Extension, Kajetan@Hinner.com, 17/10/98 | ||
| 210 | 479 : secureonlychannel # pircd | ||
| 211 | ### TODO: see above todo | ||
| 212 | ### 479 : linkfail # UnrealIrcd, Hendrik Frenzel | ||
| 213 | 480 : cannotknock # UnrealIrcd, Hendrik Frenzel | ||
| 214 | 481 : noprivileges | ||
| 215 | 482 : chanoprivsneeded | ||
| 216 | 483 : cantkillserver | ||
| 217 | 484 : ischanservice # Undernet Extension, Kajetan@Hinner.com, 17/10/98 | ||
| 218 | 485 : killdeny # UnrealIrcd, Hendrik Frenzel | ||
| 219 | 486 : htmdisabled # UnrealIrcd, Hendrik Frenzel | ||
| 220 | 489 : secureonlychan # UnrealIrcd, Hendrik Frenzel | ||
| 221 | 491 : nooperhost | ||
| 222 | 492 : noservicehost | ||
| 223 | 501 : umodeunknownflag | ||
| 224 | 502 : usersdontmatch | ||
| 225 | 511 : silelistfull # Undernet Extension, Kajetan@Hinner.com, 17/10/98 | ||
| 226 | 513 : nosuchgline # Undernet Extension, Kajetan@Hinner.com, 17/10/98 | ||
| 227 | 513 : badping # Undernet Extension, Kajetan@Hinner.com, 17/10/98 | ||
| 228 | 518 : noinvite # UnrealIrcd, Hendrik Frenzel | ||
| 229 | 519 : admonly # UnrealIrcd, Hendrik Frenzel | ||
| 230 | 520 : operonly # UnrealIrcd, Hendrik Frenzel | ||
| 231 | 521 : listsyntax # UnrealIrcd, Hendrik Frenzel | ||
| 232 | 524 : operspverify # UnrealIrcd, Hendrik Frenzel | ||
| 233 | |||
| 234 | 600 : rpl_logon # Bahamut IRCD | ||
| 235 | 601 : rpl_logoff # Bahamut IRCD | ||
| 236 | 602 : rpl_watchoff # UnrealIrcd, Hendrik Frenzel | ||
| 237 | 603 : rpl_watchstat # UnrealIrcd, Hendrik Frenzel | ||
| 238 | 604 : rpl_nowon # Bahamut IRCD | ||
| 239 | 605 : rpl_nowoff # Bahamut IRCD | ||
| 240 | 606 : rpl_watchlist # UnrealIrcd, Hendrik Frenzel | ||
| 241 | 607 : rpl_endofwatchlist # UnrealIrcd, Hendrik Frenzel | ||
| 242 | 610 : mapmore # UnrealIrcd, Hendrik Frenzel | ||
| 243 | 640 : rpl_dumping # UnrealIrcd, Hendrik Frenzel | ||
| 244 | 641 : rpl_dumprpl # UnrealIrcd, Hendrik Frenzel | ||
| 245 | 642 : rpl_eodump # UnrealIrcd, Hendrik Frenzel | ||
| 246 | |||
| 247 | 999 : numericerror # Bahamut IRCD |
lib/irc/user.rb
(0 / 27)
|   | |||
| 1 | # Represents IRC Users | ||
| 2 | module IRC | ||
| 3 | |||
| 4 | class User | ||
| 5 | @@users = Hash.new() | ||
| 6 | @modes = Hash.new() | ||
| 7 | |||
| 8 | def self.create_user(username) | ||
| 9 | username.sub!(/^[\@\%]/,'') | ||
| 10 | |||
| 11 | if @@users[username] | ||
| 12 | return @@users[username] | ||
| 13 | end | ||
| 14 | @@users[username] = self.new(username) | ||
| 15 | @@users[username] | ||
| 16 | end | ||
| 17 | |||
| 18 | attr_reader :username, :mask | ||
| 19 | attr_writer :mask | ||
| 20 | |||
| 21 | private | ||
| 22 | def initialize (username) | ||
| 23 | @username = username | ||
| 24 | end | ||
| 25 | end | ||
| 26 | |||
| 27 | end |
lib/irc/util.rb
(0 / 53)
|   | |||
| 1 | # | ||
| 2 | # IRCUtil is a module that contains utility functions for use with the | ||
| 3 | # rest of Ruby-IRC. There is nothing required of the user to know or | ||
| 4 | # even use these functions, but they are useful for certain tasks | ||
| 5 | # regarding IRC connections. | ||
| 6 | # | ||
| 7 | |||
| 8 | module IRC | ||
| 9 | |||
| 10 | module Util | ||
| 11 | # | ||
| 12 | # Matches hostmasks against hosts. Returns t/f on success/fail. | ||
| 13 | # | ||
| 14 | # A hostmask consists of a simple wildcard that describes a | ||
| 15 | # host or class of hosts. | ||
| 16 | # | ||
| 17 | # f.e., where the host is 'bar.example.com', a host mask | ||
| 18 | # of '*.example.com' would assert. | ||
| 19 | # | ||
| 20 | |||
| 21 | def assert_hostmask(host, hostmask) | ||
| 22 | return !!host.match(quote_regexp_for_mask(hostmask)) | ||
| 23 | end | ||
| 24 | |||
| 25 | module_function :assert_hostmask | ||
| 26 | |||
| 27 | # | ||
| 28 | # A utility function used by assert_hostmask() to turn hostmasks | ||
| 29 | # into regular expressions. | ||
| 30 | # | ||
| 31 | # Rarely, if ever, should be used by outside code. It's public | ||
| 32 | # exposure is merely for those who are interested in it's | ||
| 33 | # functionality. | ||
| 34 | # | ||
| 35 | |||
| 36 | def quote_regexp_for_mask(hostmask) | ||
| 37 | # Big thanks to Jesse Williamson for his consultation while writing this. | ||
| 38 | # | ||
| 39 | # escape all other regexp specials except for . and *. | ||
| 40 | # properly escape . and place an unescaped . before *. | ||
| 41 | # confine the regexp to scan the whole line. | ||
| 42 | # return the edited hostmask as a string. | ||
| 43 | hostmask.gsub(/([\[\]\(\)\?\^\$])\\/, '\\1'). | ||
| 44 | gsub(/\./, '\.'). | ||
| 45 | gsub(/\*/, '.*'). | ||
| 46 | sub(/^/, '^'). | ||
| 47 | sub(/$/, '$') | ||
| 48 | end | ||
| 49 | |||
| 50 | module_function :quote_regexp_for_mask | ||
| 51 | end | ||
| 52 | |||
| 53 | end |
lib/rif/bot.rb
(34 / 0)
|   | |||
| 1 | |||
| 2 | require 'rif/botbase' | ||
| 3 | |||
| 4 | module RIF | ||
| 5 | |||
| 6 | class Bot < BotBase | ||
| 7 | attr_accessor :operator | ||
| 8 | def initialize(nick, server, port, realname='RBot') | ||
| 9 | super | ||
| 10 | |||
| 11 | @operator = "%" | ||
| 12 | end | ||
| 13 | |||
| 14 | def on_privmsg(event) | ||
| 15 | if event.message =~ /^#{@operator}(\w+)(\s|.+)*/ | ||
| 16 | command = $1 | ||
| 17 | args = $2.to_s.split(/\s+/) | ||
| 18 | method = "do_#{command}".to_sym | ||
| 19 | |||
| 20 | if respond_to?(method) | ||
| 21 | if respond_to?(method) | ||
| 22 | __send__(method, event, args) | ||
| 23 | return true | ||
| 24 | end | ||
| 25 | else | ||
| 26 | $stderr.puts "Invalid action: #{command} from #{event.from} in #{event.channel}" | ||
| 27 | end | ||
| 28 | end | ||
| 29 | |||
| 30 | on_message(event) if respond_to?(:on_message) | ||
| 31 | end | ||
| 32 | end | ||
| 33 | |||
| 34 | end |
lib/rif/botbase.rb
(178 / 0)
|   | |||
| 1 | |||
| 2 | require 'socket' | ||
| 3 | require 'rif/connection' | ||
| 4 | require 'rif/event' | ||
| 5 | require 'rif/channel' | ||
| 6 | require 'rif/user' | ||
| 7 | require 'rif/util' | ||
| 8 | |||
| 9 | module RIF | ||
| 10 | |||
| 11 | # Class IRC is a master class that handles connection to the irc | ||
| 12 | # server and pasring of IRC events, through the Event class. | ||
| 13 | class BotBase | ||
| 14 | attr_reader :nick, :server, :port | ||
| 15 | |||
| 16 | @channels = nil | ||
| 17 | # Create a new IRC Object instance | ||
| 18 | def initialize( nick, server, port, realname='RIFY') | ||
| 19 | @nick = nick | ||
| 20 | @server = server | ||
| 21 | @port = port | ||
| 22 | @realname = realname | ||
| 23 | @channels = Array.new(0) | ||
| 24 | # Some good default Event handlers. These can and will be overridden by users. | ||
| 25 | # Thses make changes on the IRCbot object. So they need to be here. | ||
| 26 | |||
| 27 | # Topic events can come on two tags, so we create on proc to handle them. | ||
| 28 | |||
| 29 | topic_proc = Proc.new { |event| | ||
| 30 | self.channels.each { |chan| | ||
| 31 | if chan == event.channel | ||
| 32 | chan.topic = event.message | ||
| 33 | end | ||
| 34 | } | ||
| 35 | } | ||
| 36 | |||
| 37 | Event.add_handler('332', topic_proc) | ||
| 38 | Event.add_handler('topic', topic_proc) | ||
| 39 | |||
| 40 | unhandle_proc = Proc.new { |event| | ||
| 41 | method_id = "on_#{event.type}".to_sym | ||
| 42 | if respond_to?(method_id) | ||
| 43 | __send__(method_id, event) | ||
| 44 | elsif $DEBUG | ||
| 45 | $stderr.puts "=> Undefined method #{method_id}" | ||
| 46 | end | ||
| 47 | } | ||
| 48 | |||
| 49 | Event.add_handler("generic_handler", unhandle_proc) | ||
| 50 | end | ||
| 51 | |||
| 52 | # Join a channel, adding it to the list of joined channels | ||
| 53 | def add_channel channel | ||
| 54 | join(channel) | ||
| 55 | self | ||
| 56 | end | ||
| 57 | |||
| 58 | # Returns a list of channels joined | ||
| 59 | def channels | ||
| 60 | @channels | ||
| 61 | end | ||
| 62 | |||
| 63 | # Open a connection to the server using the IRC Connect | ||
| 64 | # method. Events yielded from the Connection handler are | ||
| 65 | # processed and then control is returned to Connection | ||
| 66 | def connect | ||
| 67 | quithandler = lambda { send_quit(); Connection.quit; exit 0 } | ||
| 68 | trap("INT", quithandler) | ||
| 69 | trap("TERM", quithandler) | ||
| 70 | |||
| 71 | Connection.handle_connection(@server, @port, @nick, @realname) do | ||
| 72 | # Log in information moved to Connection | ||
| 73 | @threads = [] | ||
| 74 | Connection.main do |event| | ||
| 75 | if event.kind_of?(Array) | ||
| 76 | event.each {|event| | ||
| 77 | thread_event(event) | ||
| 78 | } | ||
| 79 | else | ||
| 80 | thread_event(event) | ||
| 81 | end | ||
| 82 | end | ||
| 83 | @threads.each {|thr| thr.join } | ||
| 84 | end | ||
| 85 | end | ||
| 86 | alias start connect | ||
| 87 | |||
| 88 | # Joins a channel on a server. | ||
| 89 | def join(*channels) | ||
| 90 | channels.each { |channel| | ||
| 91 | if (Connection.send_to_server("JOIN #{channel}")) | ||
| 92 | @channels.push(Channel.new(channel)); | ||
| 93 | end | ||
| 94 | } | ||
| 95 | end | ||
| 96 | |||
| 97 | # Leaves a channel on a server | ||
| 98 | def part(channel) | ||
| 99 | if (Connection.send_to_server("PART #{channel}")) | ||
| 100 | @channels.delete_if {|chan| chan.name == channel } | ||
| 101 | end | ||
| 102 | end | ||
| 103 | |||
| 104 | # kicks a user from a channel (does not check for operator privledge) | ||
| 105 | def kick(channel, user, message) | ||
| 106 | Connection.send_to_server("KICK #{channel} #{user} :#{message || user || 'kicked'}") | ||
| 107 | end | ||
| 108 | |||
| 109 | # sets the topic of the given channel | ||
| 110 | def set_topic(channel, topic) | ||
| 111 | Connection.send_to_server("TOPIC #{channel} :#{topic}"); | ||
| 112 | end | ||
| 113 | |||
| 114 | # Sends a private message, or channel message | ||
| 115 | def send_message(to, message) | ||
| 116 | Connection.send_to_server("privmsg #{to} :#{message}"); | ||
| 117 | end | ||
| 118 | |||
| 119 | # Sends a notice | ||
| 120 | def send_notice(to, message) | ||
| 121 | Connection.send_to_server("NOTICE #{to} :#{message}"); | ||
| 122 | end | ||
| 123 | |||
| 124 | # performs an action | ||
| 125 | def send_action(to, action) | ||
| 126 | send_ctcp(to, 'ACTION', action); | ||
| 127 | end | ||
| 128 | |||
| 129 | # send CTCP | ||
| 130 | def send_ctcp(to, type, message) | ||
| 131 | Connection.send_to_server("privmsg #{to} :\001#{type} #{message}"); | ||
| 132 | end | ||
| 133 | |||
| 134 | # Quits the IRC Server | ||
| 135 | def send_quit | ||
| 136 | Connection.send_to_server("QUIT : Quit ordered by user") | ||
| 137 | end | ||
| 138 | |||
| 139 | # Ops selected user. | ||
| 140 | def op(channel, user) | ||
| 141 | Connection.send_to_server("MODE #{channel} +o #{user}") | ||
| 142 | end | ||
| 143 | |||
| 144 | # Changes the current nickname | ||
| 145 | def ch_nick(nick) | ||
| 146 | Connection.send_to_server("NICK #{nick}") | ||
| 147 | @nick = nick | ||
| 148 | end | ||
| 149 | |||
| 150 | # Removes operator status from a user | ||
| 151 | def deop(channel, user) | ||
| 152 | Connection.send_to_server("MODE #{channel} -o #{user}") | ||
| 153 | end | ||
| 154 | |||
| 155 | # Changes target users mode | ||
| 156 | def mode(channel, user, mode) | ||
| 157 | Connection.send_to_server("MODE #{channel} #{mode} #{user}") | ||
| 158 | end | ||
| 159 | |||
| 160 | # Retrievs user information from the server | ||
| 161 | def get_user_info(user) | ||
| 162 | Connection.send_to_server("WHO #{user}") | ||
| 163 | end | ||
| 164 | private | ||
| 165 | def thread_event(event) | ||
| 166 | @threads << Thread.new(event) { |localevent| | ||
| 167 | begin | ||
| 168 | localevent.process | ||
| 169 | rescue => e | ||
| 170 | puts "Error: #{e.message}" | ||
| 171 | puts e.backtrace.map { |e| " from #{e}\n" } | ||
| 172 | exit -1 | ||
| 173 | end | ||
| 174 | } | ||
| 175 | end | ||
| 176 | end | ||
| 177 | |||
| 178 | end |
lib/rif/channel.rb
(34 / 0)
|   | |||
| 1 | require "rif/user" | ||
| 2 | |||
| 3 | module RIF | ||
| 4 | |||
| 5 | # Represents an IRC Channel | ||
| 6 | class Channel | ||
| 7 | attr_reader :name, :users | ||
| 8 | |||
| 9 | def initialize(name) | ||
| 10 | @name = name | ||
| 11 | @users = Array.new(0) | ||
| 12 | end | ||
| 13 | |||
| 14 | # set the topic on this channel | ||
| 15 | def topic=(topic) | ||
| 16 | @topic = topic | ||
| 17 | end | ||
| 18 | |||
| 19 | # get the topic on this channel | ||
| 20 | def topic | ||
| 21 | if @topic | ||
| 22 | return @topic | ||
| 23 | end | ||
| 24 | return "No Topic set" | ||
| 25 | end | ||
| 26 | |||
| 27 | # add a user to this channel's userlist | ||
| 28 | def add_user(username) | ||
| 29 | @users.push(RIF::User.create_user(username)) | ||
| 30 | end | ||
| 31 | end | ||
| 32 | |||
| 33 | |||
| 34 | end |
lib/rif/connection.rb
(124 / 0)
|   | |||
| 1 | |||
| 2 | |||
| 3 | |||
| 4 | module RIF | ||
| 5 | |||
| 6 | # Handles connection to IRC Server | ||
| 7 | class Connection | ||
| 8 | @@quit = 0 | ||
| 9 | @@readsockets = Array.new(0) | ||
| 10 | @@output_buffer = Array.new(0) | ||
| 11 | @@events = Hash.new() | ||
| 12 | @@last_send = Time.now.to_f | ||
| 13 | @@message_delay = 0.2 # Default delay to 1 fifth of a second. | ||
| 14 | # Creates a socket connection and then yields. | ||
| 15 | def self.handle_connection(server, port, nick='ChangeMe', realname='MeToo' ) | ||
| 16 | @server = server; | ||
| 17 | @port = port | ||
| 18 | @nick = nick | ||
| 19 | @realname = realname | ||
| 20 | socket = create_tcp_socket(server, port) | ||
| 21 | add_IO_socket(socket) {|sock| | ||
| 22 | begin | ||
| 23 | RIF::Event.new(sock.readline.chomp) | ||
| 24 | rescue Errno::ECONNRESET | ||
| 25 | # Catches connection reset by peer, attempts to reconnect | ||
| 26 | # after sleeping for 10 second. | ||
| 27 | remove_IO_socket(sock) | ||
| 28 | sleep 10 | ||
| 29 | handle_connection(@server, @port, @nick, @realname) | ||
| 30 | end | ||
| 31 | } | ||
| 32 | send_to_server "NICK #{nick}" | ||
| 33 | send_to_server "USER #{nick} 8 * :#{realname}" | ||
| 34 | if block_given? | ||
| 35 | yield | ||
| 36 | @@socket.close | ||
| 37 | end | ||
| 38 | end | ||
| 39 | |||
| 40 | def self.create_tcp_socket(server, port) | ||
| 41 | @@socket = TCPsocket.open(server, port) | ||
| 42 | if block_given? | ||
| 43 | yield | ||
| 44 | @@socket.close | ||
| 45 | return | ||
| 46 | end | ||
| 47 | return @@socket | ||
| 48 | end | ||
| 49 | |||
| 50 | # Sends a line of text to the server | ||
| 51 | def self.send_to_server(line) | ||
| 52 | @@socket.write(line + "\n") | ||
| 53 | end | ||
| 54 | |||
| 55 | # Adds data an output buffer. This let's us keep a handle on how | ||
| 56 | # fast we send things. Yay. | ||
| 57 | def self.output_push(line) | ||
| 58 | @@output_buffer.push(line) | ||
| 59 | end | ||
| 60 | |||
| 61 | # This loop monitors all IO_Sockets self controls | ||
| 62 | # (including the IRC socket) and yields events to the IO_Sockets | ||
| 63 | # event handler. | ||
| 64 | def self.main | ||
| 65 | while(@@quit == 0) | ||
| 66 | do_one_loop { |event| | ||
| 67 | yield event | ||
| 68 | } | ||
| 69 | end | ||
| 70 | end | ||
| 71 | |||
| 72 | # Makes one single loop pass, checking all sockets for data to read, | ||
| 73 | # and yields the data to the sockets event handler. | ||
| 74 | def self.do_one_loop | ||
| 75 | read_sockets = select(@@readsockets, nil, nil, 0.1); | ||
| 76 | if !read_sockets.nil? | ||
| 77 | read_sockets[0].each {|sock| | ||
| 78 | if sock.eof? && sock == @@socket | ||
| 79 | p "Detected Socket Close" | ||
| 80 | remove_IO_socket(sock) | ||
| 81 | sleep 10 | ||
| 82 | handle_connection(@server, @port, @nick, @realname) | ||
| 83 | else | ||
| 84 | yield @@events[sock.to_i].call(sock) | ||
| 85 | end | ||
| 86 | } | ||
| 87 | end | ||
| 88 | if @@output_buffer.length > 0 | ||
| 89 | timer = Time.now.to_f | ||
| 90 | if (timer > @@last_send + @@message_delay) | ||
| 91 | message = @@output_buffer.shift(); | ||
| 92 | if !message.nil? | ||
| 93 | self.send_to_server(message); | ||
| 94 | @@last_send = timer | ||
| 95 | end | ||
| 96 | end | ||
| 97 | end | ||
| 98 | end | ||
| 99 | |||
| 100 | # Ends connection to the irc server | ||
| 101 | def self.quit | ||
| 102 | @@quit = 1 | ||
| 103 | end | ||
| 104 | def self.delay=(delay) | ||
| 105 | @@message_delay = delay.to_f | ||
| 106 | end | ||
| 107 | # Retrieves user info from the server | ||
| 108 | def self.get_user_info(user) | ||
| 109 | self.send_to_server("WHOIS #{user}") | ||
| 110 | end | ||
| 111 | |||
| 112 | # Adds a new socket to the list of sockets to monitor for new data. | ||
| 113 | def self.add_IO_socket(socket, &event_generator) | ||
| 114 | @@readsockets.push(socket) | ||
| 115 | @@events[socket.to_i] = event_generator | ||
| 116 | end | ||
| 117 | |||
| 118 | def self.remove_IO_socket(sock) | ||
| 119 | sock.close | ||
| 120 | @@readsockets.delete_if {|item| item == sock } | ||
| 121 | end | ||
| 122 | end | ||
| 123 | |||
| 124 | end |
lib/rif/event.rb
(120 / 0)
|   | |||
| 1 | require 'yaml' | ||
| 2 | |||
| 3 | module RIF | ||
| 4 | |||
| 5 | # This is a lookup class for IRC event name mapping | ||
| 6 | class EventLookup | ||
| 7 | @@lookup = YAML.load_file("#{File.dirname(__FILE__)}/eventmap.yml") | ||
| 8 | |||
| 9 | # returns the event name, given a number | ||
| 10 | def EventLookup::find_by_number(num) | ||
| 11 | return @@lookup[num.to_i] | ||
| 12 | end | ||
| 13 | end | ||
| 14 | |||
| 15 | |||
| 16 | # Handles an IRC generated event. | ||
| 17 | # Handlers are for the IRC framework to use | ||
| 18 | # Callbacks are for users to add. | ||
| 19 | # Both handlers and callbacks can be called for the same event. | ||
| 20 | class Event | ||
| 21 | @@handlers = { 'ping' => lambda {|event| Connection.send_to_server("PONG #{event.message}") } } | ||
| 22 | @@callbacks = Hash.new() | ||
| 23 | attr_reader :hostmask, :message, :type, :from, :channel, :target, :mode, :stats, :nick, :ident | ||
| 24 | def initialize (line) | ||
| 25 | puts "FROM SERVER: #{line}" if $DEBUG | ||
| 26 | |||
| 27 | line.sub!(/^:/, '') | ||
| 28 | mess_parts = line.split(':', 2); | ||
| 29 | # mess_parts[0] is server info | ||
| 30 | # mess_parts[1] is the message that was sent | ||
| 31 | @message = (mess_parts[1] ? mess_parts[1] : "" ) | ||
| 32 | @from = "" | ||
| 33 | @channel = "" | ||
| 34 | |||
| 35 | @stats = mess_parts[0].split(" ") | ||
| 36 | |||
| 37 | puts @stats.join(" | ") if $DEBUG | ||
| 38 | |||
| 39 | if @stats[0].match(/^PING/) | ||
| 40 | @type = 'ping' | ||
| 41 | elsif @message.match(/^(\x1(\w+))/) # ctcp | ||
| 42 | @from = @stats[0] | ||
| 43 | ctcp = $2.downcase | ||
| 44 | |||
| 45 | if ctcp == "action" | ||
| 46 | @type = ctcp | ||
| 47 | else | ||
| 48 | @type = "ctcp_#{ctcp}" | ||
| 49 | end | ||
| 50 | |||
| 51 | @message.gsub!($1, "") | ||
| 52 | elsif @stats[1] && @stats[1].match(/^\d+/) | ||
| 53 | @type = EventLookup::find_by_number(@stats[1]); | ||
| 54 | @channel = @stats[2] | ||
| 55 | else | ||
| 56 | @type = @stats[1].downcase if @stats[1] | ||
| 57 | end | ||
| 58 | |||
| 59 | if @type != 'ping' | ||
| 60 | @from = @stats[0] | ||
| 61 | @user = User.create_user(@from) | ||
| 62 | end | ||
| 63 | |||
| 64 | @hostmask = @from.split("@").last | ||
| 65 | @nick = @from.split("!").first | ||
| 66 | @ident = "" | ||
| 67 | |||
| 68 | if @from =~ /!(.+)@/ | ||
| 69 | @ident = $1 | ||
| 70 | end | ||
| 71 | |||
| 72 | @channel = @stats[2] if @stats[2] and @channel.empty? | ||
| 73 | @target = @stats[3] if @stats[3] | ||
| 74 | @mode = @stats[4] if @stats[4] | ||
| 75 | |||
| 76 | # Unfortunatly, not all messages are created equal. This is our | ||
| 77 | # special exceptions section | ||
| 78 | if @type == 'join' | ||
| 79 | @channel = @message | ||
| 80 | end | ||
| 81 | |||
| 82 | puts "EVENT: #{@type}" if $DEBUG | ||
| 83 | |||
| 84 | end | ||
| 85 | |||
| 86 | # Adds a callback for the specified irc message. | ||
| 87 | def self.add_callback(message_id, &callback) | ||
| 88 | @@callbacks[message_id] = callback | ||
| 89 | end | ||
| 90 | |||
| 91 | # Adds a handler to the handler function hash. | ||
| 92 | def self.add_handler(message_id, proc=nil, &handler) | ||
| 93 | if block_given? | ||
| 94 | @@handlers[message_id] = handler | ||
| 95 | elsif proc | ||
| 96 | @@handlers[message_id] = proc | ||
| 97 | end | ||
| 98 | end | ||
| 99 | |||
| 100 | # Process this event, preforming which ever handler and callback is specified | ||
| 101 | # for this event. | ||
| 102 | def process | ||
| 103 | handled = false | ||
| 104 | if @@handlers[@type] | ||
| 105 | @@handlers[@type].call(self) | ||
| 106 | handled = true | ||
| 107 | end | ||
| 108 | |||
| 109 | if @@callbacks[@type] | ||
| 110 | @@callbacks[@type].call(self) | ||
| 111 | handled = true | ||
| 112 | end | ||
| 113 | |||
| 114 | if @@handlers["generic_handler"] | ||
| 115 | @@handlers["generic_handler"].call(self) | ||
| 116 | end | ||
| 117 | end | ||
| 118 | end | ||
| 119 | |||
| 120 | end |
lib/rif/eventmap.yml
(247 / 0)
|   | |||
| 1 | # 001 ne 1 for the purpose of hash keying apparently. | ||
| 2 | 001 : welcome | ||
| 3 | 002 : yourhost | ||
| 4 | 003 : created | ||
| 5 | 004 : myinfo | ||
| 6 | 005 : map # Undernet Extension, Kajetan@Hinner.com, 17/11/98 | ||
| 7 | 006 : mapmore # Undernet Extension, Kajetan@Hinner.com, 17/11/98 | ||
| 8 | 007 : mapend # Undernet Extension, Kajetan@Hinner.com, 17/11/98 | ||
| 9 | 008 : snomask # Undernet Extension, Kajetan@Hinner.com, 17/11/98 | ||
| 10 | 009 : statmemtot # Undernet Extension, Kajetan@Hinner.com, 17/11/98 | ||
| 11 | 010 : statmem # Undernet Extension, Kajetan@Hinner.com, 17/11/98 | ||
| 12 | 200 : tracelink | ||
| 13 | 201 : traceconnecting | ||
| 14 | 202 : tracehandshake | ||
| 15 | 203 : traceunknown | ||
| 16 | 204 : traceoperator | ||
| 17 | 205 : traceuser | ||
| 18 | 206 : traceserver | ||
| 19 | 208 : tracenewtype | ||
| 20 | 209 : traceclass | ||
| 21 | 211 : statslinkinfo | ||
| 22 | 212 : statscommands | ||
| 23 | 213 : statscline | ||
| 24 | 214 : statsnline | ||
| 25 | 215 : statsiline | ||
| 26 | 216 : statskline | ||
| 27 | 217 : statsqline | ||
| 28 | 218 : statsyline | ||
| 29 | 219 : endofstats | ||
| 30 | 220 : statsbline # UnrealIrcd, Hendrik Frenzel | ||
| 31 | 221 : umodeis | ||
| 32 | 222 : sqline_nick # UnrealIrcd, Hendrik Frenzel | ||
| 33 | 223 : statsgline # UnrealIrcd, Hendrik Frenzel | ||
| 34 | 224 : statstline # UnrealIrcd, Hendrik Frenzel | ||
| 35 | 225 : statseline # UnrealIrcd, Hendrik Frenzel | ||
| 36 | 226 : statsnline # UnrealIrcd, Hendrik Frenzel | ||
| 37 | 227 : statsvline # UnrealIrcd, Hendrik Frenzel | ||
| 38 | 231 : serviceinfo | ||
| 39 | 232 : endofservices | ||
| 40 | 233 : service | ||
| 41 | 234 : servlist | ||
| 42 | 235 : servlistend | ||
| 43 | 241 : statslline | ||
| 44 | 242 : statsuptime | ||
| 45 | 243 : statsoline | ||
| 46 | 244 : statshline | ||
| 47 | 245 : statssline # Reserved, Kajetan@Hinner.com, 17/10/98 | ||
| 48 | 246 : statstline # Undernet Extension, Kajetan@Hinner.com, 17/10/98 | ||
| 49 | 247 : statsgline # Undernet Extension, Kajetan@Hinner.com, 17/10/98 | ||
| 50 | ### TODO: need numerics to be able to map to multiple strings | ||
| 51 | ### 247 : statsxline # UnrealIrcd, Hendrik Frenzel | ||
| 52 | 248 : statsuline # Undernet Extension, Kajetan@Hinner.com, 17/10/98 | ||
| 53 | 249 : statsdebug # Unspecific Extension, Kajetan@Hinner.com, 17/10/98 | ||
| 54 | 250 : luserconns # 1998-03-15 -- tkil | ||
| 55 | 251 : luserclient | ||
| 56 | 252 : luserop | ||
| 57 | 253 : luserunknown | ||
| 58 | 254 : luserchannels | ||
| 59 | 255 : luserme | ||
| 60 | 256 : adminme | ||
| 61 | 257 : adminloc1 | ||
| 62 | 258 : adminloc2 | ||
| 63 | 259 : adminemail | ||
| 64 | 261 : tracelog | ||
| 65 | 262 : endoftrace # 1997-11-24 -- archon | ||
| 66 | 265 : n_local # 1997-10-16 -- tkil | ||
| 67 | 266 : n_global # 1997-10-16 -- tkil | ||
| 68 | 271 : silelist # Undernet Extension, Kajetan@Hinner.com, 17/10/98 | ||
| 69 | 272 : endofsilelist # Undernet Extension, Kajetan@Hinner.com, 17/10/98 | ||
| 70 | 275 : statsdline # Undernet Extension, Kajetan@Hinner.com, 17/10/98 | ||
| 71 | 280 : glist # Undernet Extension, Kajetan@Hinner.com, 17/10/98 | ||
| 72 | 281 : endofglist # Undernet Extension, Kajetan@Hinner.com, 17/10/98 | ||
| 73 | 290 : helphdr # UnrealIrcd, Hendrik Frenzel | ||
| 74 | 291 : helpop # UnrealIrcd, Hendrik Frenzel | ||
| 75 | 292 : helptlr # UnrealIrcd, Hendrik Frenzel | ||
| 76 | 293 : helphlp # UnrealIrcd, Hendrik Frenzel | ||
| 77 | 294 : helpfwd # UnrealIrcd, Hendrik Frenzel | ||
| 78 | 295 : helpign # UnrealIrcd, Hendrik Frenzel | ||
| 79 | 300 : none | ||
| 80 | 301 : away | ||
| 81 | 302 : userhost | ||
| 82 | 303 : ison | ||
| 83 | 304 : rpl_text # Bahamut IRCD | ||
| 84 | 305 : unaway | ||
| 85 | 306 : nowaway | ||
| 86 | 307 : userip # Undernet Extension, Kajetan@Hinner.com, 17/10/98 | ||
| 87 | 308 : rulesstart # UnrealIrcd, Hendrik Frenzel | ||
| 88 | 309 : endofrules # UnrealIrcd, Hendrik Frenzel | ||
| 89 | 310 : whoishelp # (July01-01)Austnet Extension, found by Andypoo <andypoo@secret.com.au> | ||
| 90 | 311 : whoisuser | ||
| 91 | 312 : whoisserver | ||
| 92 | 313 : whoisoperator | ||
| 93 | 314 : whowasuser | ||
| 94 | 315 : endofwho | ||
| 95 | 316 : whoischanop | ||
| 96 | 317 : whoisidle | ||
| 97 | 318 : endofwhois | ||
| 98 | 319 : whoischannels | ||
| 99 | 320 : whoisvworld # (July01-01)Austnet Extension, found by Andypoo <andypoo@secret.com.au> | ||
| 100 | 321 : liststart | ||
| 101 | 322 : list | ||
| 102 | 323 : listend | ||
| 103 | 324 : channelmodeis | ||
| 104 | 329 : channelcreate # 1997-11-24 -- archon | ||
| 105 | 331 : notopic | ||
| 106 | 332 : topic | ||
| 107 | 333 : topicinfo # 1997-11-24 -- archon | ||
| 108 | 334 : listusage # Undernet Extension, Kajetan@Hinner.com, 17/10/98 | ||
| 109 | 335 : whoisbot # UnrealIrcd, Hendrik Frenzel | ||
| 110 | 341 : inviting | ||
| 111 | 342 : summoning | ||
| 112 | 346 : invitelist # UnrealIrcd, Hendrik Frenzel | ||
| 113 | 347 : endofinvitelist # UnrealIrcd, Hendrik Frenzel | ||
| 114 | 348 : exlist # UnrealIrcd, Hendrik Frenzel | ||
| 115 | 349 : endofexlist # UnrealIrcd, Hendrik Frenzel | ||
| 116 | 351 : version | ||
| 117 | 352 : whoreply | ||
| 118 | 353 : namreply | ||
| 119 | 354 : whospcrpl # Undernet Extension, Kajetan@Hinner.com, 17/10/98 | ||
| 120 | 361 : killdone | ||
| 121 | 362 : closing | ||
| 122 | 363 : closeend | ||
| 123 | 364 : links | ||
| 124 | 365 : endoflinks | ||
| 125 | 366 : endofnames | ||
| 126 | 367 : banlist | ||
| 127 | 368 : endofbanlist | ||
| 128 | 369 : endofwhowas | ||
| 129 | 371 : info | ||
| 130 | 372 : motd | ||
| 131 | 373 : infostart | ||
| 132 | 374 : endofinfo | ||
| 133 | 375 : motdstart | ||
| 134 | 376 : endofmotd | ||
| 135 | 377 : motd2 # 1997-10-16 -- tkil | ||
| 136 | 378 : austmotd # (July01-01)Austnet Extension, found by Andypoo <andypoo@secret.com.au> | ||
| 137 | 379 : whoismodes # UnrealIrcd, Hendrik Frenzel | ||
| 138 | 381 : youreoper | ||
| 139 | 382 : rehashing | ||
| 140 | 383 : youreservice # UnrealIrcd, Hendrik Frenzel | ||
| 141 | 384 : myportis | ||
| 142 | 385 : notoperanymore # Unspecific Extension, Kajetan@Hinner.com, 17/10/98 | ||
| 143 | 386 : qlist # UnrealIrcd, Hendrik Frenzel | ||
| 144 | 387 : endofqlist # UnrealIrcd, Hendrik Frenzel | ||
| 145 | 388 : alist # UnrealIrcd, Hendrik Frenzel | ||
| 146 | 389 : endofalist # UnrealIrcd, Hendrik Frenzel | ||
| 147 | 391 : time | ||
| 148 | 392 : usersstart | ||
| 149 | 393 : users | ||
| 150 | 394 : endofusers | ||
| 151 | 395 : nousers | ||
| 152 | 401 : nosuchnick | ||
| 153 | 402 : nosuchserver | ||
| 154 | 403 : nosuchchannel | ||
| 155 | 404 : cannotsendtochan | ||
| 156 | 405 : toomanychannels | ||
| 157 | 406 : wasnosuchnick | ||
| 158 | 407 : toomanytargets | ||
| 159 | 408 : nosuchservice # UnrealIrcd, Hendrik Frenzel | ||
| 160 | 409 : noorigin | ||
| 161 | 411 : norecipient | ||
| 162 | 412 : notexttosend | ||
| 163 | 413 : notoplevel | ||
| 164 | 414 : wildtoplevel | ||
| 165 | 416 : querytoolong # Undernet Extension, Kajetan@Hinner.com, 17/10/98 | ||
| 166 | 421 : unknowncommand | ||
| 167 | 422 : nomotd | ||
| 168 | 423 : noadmininfo | ||
| 169 | 424 : fileerror | ||
| 170 | 425 : noopermotd # UnrealIrcd, Hendrik Frenzel | ||
| 171 | 431 : nonicknamegiven | ||
| 172 | 432 : erroneusnickname # This iz how its speld in thee RFC. | ||
| 173 | 433 : nicknameinuse | ||
| 174 | 434 : norules # UnrealIrcd, Hendrik Frenzel | ||
| 175 | 435 : serviceconfused # UnrealIrcd, Hendrik Frenzel | ||
| 176 | 436 : nickcollision | ||
| 177 | 437 : bannickchange # Undernet Extension, Kajetan@Hinner.com, 17/10/98 | ||
| 178 | 438 : nicktoofast # Undernet Extension, Kajetan@Hinner.com, 17/10/98 | ||
| 179 | 439 : targettoofast # Undernet Extension, Kajetan@Hinner.com, 17/10/98 | ||
| 180 | 440 : servicesdown # Bahamut IRCD | ||
| 181 | 441 : usernotinchannel | ||
| 182 | 442 : notonchannel | ||
| 183 | 443 : useronchannel | ||
| 184 | 444 : nologin | ||
| 185 | 445 : summondisabled | ||
| 186 | 446 : usersdisabled | ||
| 187 | 447 : nonickchange # UnrealIrcd, Hendrik Frenzel | ||
| 188 | 451 : notregistered | ||
| 189 | 455 : hostilename # UnrealIrcd, Hendrik Frenzel | ||
| 190 | 459 : nohiding # UnrealIrcd, Hendrik Frenzel | ||
| 191 | 460 : notforhalfops # UnrealIrcd, Hendrik Frenzel | ||
| 192 | 461 : needmoreparams | ||
| 193 | 462 : alreadyregistered | ||
| 194 | 463 : nopermforhost | ||
| 195 | 464 : passwdmismatch | ||
| 196 | 465 : yourebannedcreep # I love this one... | ||
| 197 | 466 : youwillbebanned | ||
| 198 | 467 : keyset | ||
| 199 | 468 : invalidusername # Undernet Extension, Kajetan@Hinner.com, 17/10/98 | ||
| 200 | 469 : linkset # UnrealIrcd, Hendrik Frenzel | ||
| 201 | 470 : linkchannel # UnrealIrcd, Hendrik Frenzel | ||
| 202 | 471 : channelisfull | ||
| 203 | 472 : unknownmode | ||
| 204 | 473 : inviteonlychan | ||
| 205 | 474 : bannedfromchan | ||
| 206 | 475 : badchannelkey | ||
| 207 | 476 : badchanmask | ||
| 208 | 477 : needreggednick # Bahamut IRCD | ||
| 209 | 478 : banlistfull # Undernet Extension, Kajetan@Hinner.com, 17/10/98 | ||
| 210 | 479 : secureonlychannel # pircd | ||
| 211 | ### TODO: see above todo | ||
| 212 | ### 479 : linkfail # UnrealIrcd, Hendrik Frenzel | ||
| 213 | 480 : cannotknock # UnrealIrcd, Hendrik Frenzel | ||
| 214 | 481 : noprivileges | ||
| 215 | 482 : chanoprivsneeded | ||
| 216 | 483 : cantkillserver | ||
| 217 | 484 : ischanservice # Undernet Extension, Kajetan@Hinner.com, 17/10/98 | ||
| 218 | 485 : killdeny # UnrealIrcd, Hendrik Frenzel | ||
| 219 | 486 : htmdisabled # UnrealIrcd, Hendrik Frenzel | ||
| 220 | 489 : secureonlychan # UnrealIrcd, Hendrik Frenzel | ||
| 221 | 491 : nooperhost | ||
| 222 | 492 : noservicehost | ||
| 223 | 501 : umodeunknownflag | ||
| 224 | 502 : usersdontmatch | ||
| 225 | 511 : silelistfull # Undernet Extension, Kajetan@Hinner.com, 17/10/98 | ||
| 226 | 513 : nosuchgline # Undernet Extension, Kajetan@Hinner.com, 17/10/98 | ||
| 227 | 513 : badping # Undernet Extension, Kajetan@Hinner.com, 17/10/98 | ||
| 228 | 518 : noinvite # UnrealIrcd, Hendrik Frenzel | ||
| 229 | 519 : admonly # UnrealIrcd, Hendrik Frenzel | ||
| 230 | 520 : operonly # UnrealIrcd, Hendrik Frenzel | ||
| 231 | 521 : listsyntax # UnrealIrcd, Hendrik Frenzel | ||
| 232 | 524 : operspverify # UnrealIrcd, Hendrik Frenzel | ||
| 233 | |||
| 234 | 600 : rpl_logon # Bahamut IRCD | ||
| 235 | 601 : rpl_logoff # Bahamut IRCD | ||
| 236 | 602 : rpl_watchoff # UnrealIrcd, Hendrik Frenzel | ||
| 237 | 603 : rpl_watchstat # UnrealIrcd, Hendrik Frenzel | ||
| 238 | 604 : rpl_nowon # Bahamut IRCD | ||
| 239 | 605 : rpl_nowoff # Bahamut IRCD | ||
| 240 | 606 : rpl_watchlist # UnrealIrcd, Hendrik Frenzel | ||
| 241 | 607 : rpl_endofwatchlist # UnrealIrcd, Hendrik Frenzel | ||
| 242 | 610 : mapmore # UnrealIrcd, Hendrik Frenzel | ||
| 243 | 640 : rpl_dumping # UnrealIrcd, Hendrik Frenzel | ||
| 244 | 641 : rpl_dumprpl # UnrealIrcd, Hendrik Frenzel | ||
| 245 | 642 : rpl_eodump # UnrealIrcd, Hendrik Frenzel | ||
| 246 | |||
| 247 | 999 : numericerror # Bahamut IRCD |
lib/rif/user.rb
(27 / 0)
|   | |||
| 1 | # Represents IRC Users | ||
| 2 | module RIF | ||
| 3 | |||
| 4 | class User | ||
| 5 | @@users = Hash.new() | ||
| 6 | @modes = Hash.new() | ||
| 7 | |||
| 8 | def self.create_user(username) | ||
| 9 | username.sub!(/^[\@\%]/,'') | ||
| 10 | |||
| 11 | if @@users[username] | ||
| 12 | return @@users[username] | ||
| 13 | end | ||
| 14 | @@users[username] = self.new(username) | ||
| 15 | @@users[username] | ||
| 16 | end | ||
| 17 | |||
| 18 | attr_reader :username, :mask | ||
| 19 | attr_writer :mask | ||
| 20 | |||
| 21 | private | ||
| 22 | def initialize (username) | ||
| 23 | @username = username | ||
| 24 | end | ||
| 25 | end | ||
| 26 | |||
| 27 | end |
lib/rif/util.rb
(53 / 0)
|   | |||
| 1 | # | ||
| 2 | # IRCUtil is a module that contains utility functions for use with the | ||
| 3 | # rest of Ruby-IRC. There is nothing required of the user to know or | ||
| 4 | # even use these functions, but they are useful for certain tasks | ||
| 5 | # regarding IRC connections. | ||
| 6 | # | ||
| 7 | |||
| 8 | module RIF | ||
| 9 | |||
| 10 | module Util | ||
| 11 | # | ||
| 12 | # Matches hostmasks against hosts. Returns t/f on success/fail. | ||
| 13 | # | ||
| 14 | # A hostmask consists of a simple wildcard that describes a | ||
| 15 | # host or class of hosts. | ||
| 16 | # | ||
| 17 | # f.e., where the host is 'bar.example.com', a host mask | ||
| 18 | # of '*.example.com' would assert. | ||
| 19 | # | ||
| 20 | |||
| 21 | def assert_hostmask(host, hostmask) | ||
| 22 | return !!host.match(quote_regexp_for_mask(hostmask)) | ||
| 23 | end | ||
| 24 | |||
| 25 | module_function :assert_hostmask | ||
| 26 | |||
| 27 | # | ||
| 28 | # A utility function used by assert_hostmask() to turn hostmasks | ||
| 29 | # into regular expressions. | ||
| 30 | # | ||
| 31 | # Rarely, if ever, should be used by outside code. It's public | ||
| 32 | # exposure is merely for those who are interested in it's | ||
| 33 | # functionality. | ||
| 34 | # | ||
| 35 | |||
| 36 | def quote_regexp_for_mask(hostmask) | ||
| 37 | # Big thanks to Jesse Williamson for his consultation while writing this. | ||
| 38 | # | ||
| 39 | # escape all other regexp specials except for . and *. | ||
| 40 | # properly escape . and place an unescaped . before *. | ||
| 41 | # confine the regexp to scan the whole line. | ||
| 42 | # return the edited hostmask as a string. | ||
| 43 | hostmask.gsub(/([\[\]\(\)\?\^\$])\\/, '\\1'). | ||
| 44 | gsub(/\./, '\.'). | ||
| 45 | gsub(/\*/, '.*'). | ||
| 46 | sub(/^/, '^'). | ||
| 47 | sub(/$/, '$') | ||
| 48 | end | ||
| 49 | |||
| 50 | module_function :quote_regexp_for_mask | ||
| 51 | end | ||
| 52 | |||
| 53 | end |
tasks/distribution.rake
(10 / 12)
|   | |||
| 1 | 1 | ||
| 2 | 2 | ||
| 3 | PROJECT_NAME = PKG_NAME = 'rubyirc' | ||
| 3 | PROJECT_NAME = PKG_NAME = 'rif' | ||
| 4 | 4 | ||
| 5 | PKG_VERSION = "1.9" | ||
| 5 | PKG_VERSION = "0.1" | ||
| 6 | 6 | PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}" | |
| 7 | 7 | ||
| 8 | 8 | def get_files(dir) | |
| … | … | ||
| 19 | 19 | desc 'Generate RDoc' | |
| 20 | 20 | rd = Rake::RDocTask.new do |rdoc| | |
| 21 | 21 | rdoc.rdoc_dir = 'doc/output/rdoc' | |
| 22 | rdoc.options << '--title' << 'Docurb' << '--line-numbers' << | ||
| 22 | rdoc.options << '--title' << 'Ruby IRC Framework' << '--line-numbers' << | ||
| 23 | 23 | '--inline-source' << '--accessor' << 'delegate' << '--main' << 'README' | |
| 24 | 24 | # rdoc.rdoc_files.include('README', 'CHANGES', 'LGPL-LICENSE', 'lib/**/*.rb') | |
| 25 | 25 | end | |
| … | … | ||
| 29 | 29 | s.version = PKG_VERSION | |
| 30 | 30 | s.summary = 'Application to read/browse ruby documentation' | |
| 31 | 31 | s.description = <<-end_description | |
| 32 | Application to read/browse ruby documentation | ||
| 32 | Ruby IRC Framework | ||
| 33 | 33 | end_description | |
| 34 | 34 | ||
| 35 | |||
| 36 | |||
| 37 | 35 | s.files = FileList[ | |
| 38 | 36 | '[A-Z]*', | |
| 39 | 'lib/irc/*.rb', | ||
| 40 | 'lib/irc/eventmap.yml', | ||
| 37 | 'lib/rif/*.rb', | ||
| 38 | 'lib/rif/eventmap.yml', | ||
| 41 | 39 | 'examples/*.rb' | |
| 42 | 40 | ].to_a | |
| 43 | 41 | ||
| 44 | s.autorequire = 'rubyirc' | ||
| 42 | s.autorequire = 'rif' | ||
| 45 | 43 | s.author = ["David A. Cuadrado"] | |
| 46 | 44 | s.email = "krawek@gmail.com" | |
| 47 | s.homepage = "http://gitorious.org/projects/rubyirc" | ||
| 45 | s.homepage = "http://gitorious.org/projects/ruby-irc" | ||
| 48 | 46 | # s.rubyforge_project = "???" | |
| 49 | 47 | end | |
| 50 | 48 | ||
| … | … | ||
| 53 | 53 | end | |
| 54 | 54 | ||
| 55 | 55 | desc "Publish #{PKG_NAME} packages on RubyForge" | |
| 56 | task :publish_ruby_irc_packages => [:verify_user, :package] do | ||
| 56 | task :publish_packages => [:verify_user, :package] do | ||
| 57 | 57 | release_files = FileList[ | |
| 58 | 58 | "pkg/#{PKG_FILE_NAME}.gem", | |
| 59 | 59 | "pkg/#{PKG_FILE_NAME}.tgz", | |
| … | … | ||
| 65 | 65 | Rake::XForge::Release.new(MetaProject::Project::XForge::RubyForge.new(PROJECT_NAME)) do |xf| | |
| 66 | 66 | xf.user_name = ENV['RUBYFORGE_USER'] | |
| 67 | 67 | xf.files = release_files.to_a | |
| 68 | xf.release_name = "rubyirc #{PKG_VERSION}" | ||
| 68 | xf.release_name = "rif #{PKG_VERSION}" | ||
| 69 | 69 | end | |
| 70 | 70 | end |

