Commit b403ce19bf250a85ef8d1866375413736c19a8a7

Renamed to RIF (Ruby Irc Framework)
INSTALL
(3 / 0)
  
1
2rake gem
3gem install pkg/rif-0.1.gem
README
(24 / 0)
  
1
2== Install
3
4gem install rif
5
6
7== Example
8
9require 'rubygems'
10gem 'rif'
11
12require 'rif/bot'
13
14class 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
21end
22
23bot = Bot.new("bot", "irc.freenode.net", 6667, "RIF Bot")
24bot.connect
  
22
33$: << File.join(File.dirname(__FILE__), "../lib/")
44
5require 'irc/bot'
5require 'rif/bot'
66
7class MyBot < IRC::Bot
7class MyBot < RIF::Bot
88 def initialize(nick, server, port, name)
99 super
1010 end
  
1
2require 'irc/botbase'
3
4module IRC
5
6class 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
32end
33
34end
  
1
2require 'socket'
3require 'irc/connection'
4require 'irc/event'
5require 'irc/channel'
6require 'irc/user'
7require 'irc/util'
8
9module 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.
13class 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
176end
177
178end
  
1require "irc/user"
2
3module IRC
4
5# Represents an IRC Channel
6class 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
35end
36
37
38end
  
1
2
3
4module IRC
5
6# Handles connection to IRC Server
7class 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
122end
123
124end
  
1require 'yaml'
2
3module IRC
4
5# This is a lookup class for IRC event name mapping
6class 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
13end
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.
20class 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
117end
118
119end
  
1# 001 ne 1 for the purpose of hash keying apparently.
2001 : welcome
3002 : yourhost
4003 : created
5004 : myinfo
6005 : map # Undernet Extension, Kajetan@Hinner.com, 17/11/98
7006 : mapmore # Undernet Extension, Kajetan@Hinner.com, 17/11/98
8007 : mapend # Undernet Extension, Kajetan@Hinner.com, 17/11/98
9008 : snomask # Undernet Extension, Kajetan@Hinner.com, 17/11/98
10009 : statmemtot # Undernet Extension, Kajetan@Hinner.com, 17/11/98
11010 : statmem # Undernet Extension, Kajetan@Hinner.com, 17/11/98
12200 : tracelink
13201 : traceconnecting
14202 : tracehandshake
15203 : traceunknown
16204 : traceoperator
17205 : traceuser
18206 : traceserver
19208 : tracenewtype
20209 : traceclass
21211 : statslinkinfo
22212 : statscommands
23213 : statscline
24214 : statsnline
25215 : statsiline
26216 : statskline
27217 : statsqline
28218 : statsyline
29219 : endofstats
30220 : statsbline # UnrealIrcd, Hendrik Frenzel
31221 : umodeis
32222 : sqline_nick # UnrealIrcd, Hendrik Frenzel
33223 : statsgline # UnrealIrcd, Hendrik Frenzel
34224 : statstline # UnrealIrcd, Hendrik Frenzel
35225 : statseline # UnrealIrcd, Hendrik Frenzel
36226 : statsnline # UnrealIrcd, Hendrik Frenzel
37227 : statsvline # UnrealIrcd, Hendrik Frenzel
38231 : serviceinfo
39232 : endofservices
40233 : service
41234 : servlist
42235 : servlistend
43241 : statslline
44242 : statsuptime
45243 : statsoline
46244 : statshline
47245 : statssline # Reserved, Kajetan@Hinner.com, 17/10/98
48246 : statstline # Undernet Extension, Kajetan@Hinner.com, 17/10/98
49247 : 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
52248 : statsuline # Undernet Extension, Kajetan@Hinner.com, 17/10/98
53249 : statsdebug # Unspecific Extension, Kajetan@Hinner.com, 17/10/98
54250 : luserconns # 1998-03-15 -- tkil
55251 : luserclient
56252 : luserop
57253 : luserunknown
58254 : luserchannels
59255 : luserme
60256 : adminme
61257 : adminloc1
62258 : adminloc2
63259 : adminemail
64261 : tracelog
65262 : endoftrace # 1997-11-24 -- archon
66265 : n_local # 1997-10-16 -- tkil
67266 : n_global # 1997-10-16 -- tkil
68271 : silelist # Undernet Extension, Kajetan@Hinner.com, 17/10/98
69272 : endofsilelist # Undernet Extension, Kajetan@Hinner.com, 17/10/98
70275 : statsdline # Undernet Extension, Kajetan@Hinner.com, 17/10/98
71280 : glist # Undernet Extension, Kajetan@Hinner.com, 17/10/98
72281 : endofglist # Undernet Extension, Kajetan@Hinner.com, 17/10/98
73290 : helphdr # UnrealIrcd, Hendrik Frenzel
74291 : helpop # UnrealIrcd, Hendrik Frenzel
75292 : helptlr # UnrealIrcd, Hendrik Frenzel
76293 : helphlp # UnrealIrcd, Hendrik Frenzel
77294 : helpfwd # UnrealIrcd, Hendrik Frenzel
78295 : helpign # UnrealIrcd, Hendrik Frenzel
79300 : none
80301 : away
81302 : userhost
82303 : ison
83304 : rpl_text # Bahamut IRCD
84305 : unaway
85306 : nowaway
86307 : userip # Undernet Extension, Kajetan@Hinner.com, 17/10/98
87308 : rulesstart # UnrealIrcd, Hendrik Frenzel
88309 : endofrules # UnrealIrcd, Hendrik Frenzel
89310 : whoishelp # (July01-01)Austnet Extension, found by Andypoo <andypoo@secret.com.au>
90311 : whoisuser
91312 : whoisserver
92313 : whoisoperator
93314 : whowasuser
94315 : endofwho
95316 : whoischanop
96317 : whoisidle
97318 : endofwhois
98319 : whoischannels
99320 : whoisvworld # (July01-01)Austnet Extension, found by Andypoo <andypoo@secret.com.au>
100321 : liststart
101322 : list
102323 : listend
103324 : channelmodeis
104329 : channelcreate # 1997-11-24 -- archon
105331 : notopic
106332 : topic
107333 : topicinfo # 1997-11-24 -- archon
108334 : listusage # Undernet Extension, Kajetan@Hinner.com, 17/10/98
109335 : whoisbot # UnrealIrcd, Hendrik Frenzel
110341 : inviting
111342 : summoning
112346 : invitelist # UnrealIrcd, Hendrik Frenzel
113347 : endofinvitelist # UnrealIrcd, Hendrik Frenzel
114348 : exlist # UnrealIrcd, Hendrik Frenzel
115349 : endofexlist # UnrealIrcd, Hendrik Frenzel
116351 : version
117352 : whoreply
118353 : namreply
119354 : whospcrpl # Undernet Extension, Kajetan@Hinner.com, 17/10/98
120361 : killdone
121362 : closing
122363 : closeend
123364 : links
124365 : endoflinks
125366 : endofnames
126367 : banlist
127368 : endofbanlist
128369 : endofwhowas
129371 : info
130372 : motd
131373 : infostart
132374 : endofinfo
133375 : motdstart
134376 : endofmotd
135377 : motd2 # 1997-10-16 -- tkil
136378 : austmotd # (July01-01)Austnet Extension, found by Andypoo <andypoo@secret.com.au>
137379 : whoismodes # UnrealIrcd, Hendrik Frenzel
138381 : youreoper
139382 : rehashing
140383 : youreservice # UnrealIrcd, Hendrik Frenzel
141384 : myportis
142385 : notoperanymore # Unspecific Extension, Kajetan@Hinner.com, 17/10/98
143386 : qlist # UnrealIrcd, Hendrik Frenzel
144387 : endofqlist # UnrealIrcd, Hendrik Frenzel
145388 : alist # UnrealIrcd, Hendrik Frenzel
146389 : endofalist # UnrealIrcd, Hendrik Frenzel
147391 : time
148392 : usersstart
149393 : users
150394 : endofusers
151395 : nousers
152401 : nosuchnick
153402 : nosuchserver
154403 : nosuchchannel
155404 : cannotsendtochan
156405 : toomanychannels
157406 : wasnosuchnick
158407 : toomanytargets
159408 : nosuchservice # UnrealIrcd, Hendrik Frenzel
160409 : noorigin
161411 : norecipient
162412 : notexttosend
163413 : notoplevel
164414 : wildtoplevel
165416 : querytoolong # Undernet Extension, Kajetan@Hinner.com, 17/10/98
166421 : unknowncommand
167422 : nomotd
168423 : noadmininfo
169424 : fileerror
170425 : noopermotd # UnrealIrcd, Hendrik Frenzel
171431 : nonicknamegiven
172432 : erroneusnickname # This iz how its speld in thee RFC.
173433 : nicknameinuse
174434 : norules # UnrealIrcd, Hendrik Frenzel
175435 : serviceconfused # UnrealIrcd, Hendrik Frenzel
176436 : nickcollision
177437 : bannickchange # Undernet Extension, Kajetan@Hinner.com, 17/10/98
178438 : nicktoofast # Undernet Extension, Kajetan@Hinner.com, 17/10/98
179439 : targettoofast # Undernet Extension, Kajetan@Hinner.com, 17/10/98
180440 : servicesdown # Bahamut IRCD
181441 : usernotinchannel
182442 : notonchannel
183443 : useronchannel
184444 : nologin
185445 : summondisabled
186446 : usersdisabled
187447 : nonickchange # UnrealIrcd, Hendrik Frenzel
188451 : notregistered
189455 : hostilename # UnrealIrcd, Hendrik Frenzel
190459 : nohiding # UnrealIrcd, Hendrik Frenzel
191460 : notforhalfops # UnrealIrcd, Hendrik Frenzel
192461 : needmoreparams
193462 : alreadyregistered
194463 : nopermforhost
195464 : passwdmismatch
196465 : yourebannedcreep # I love this one...
197466 : youwillbebanned
198467 : keyset
199468 : invalidusername # Undernet Extension, Kajetan@Hinner.com, 17/10/98
200469 : linkset # UnrealIrcd, Hendrik Frenzel
201470 : linkchannel # UnrealIrcd, Hendrik Frenzel
202471 : channelisfull
203472 : unknownmode
204473 : inviteonlychan
205474 : bannedfromchan
206475 : badchannelkey
207476 : badchanmask
208477 : needreggednick # Bahamut IRCD
209478 : banlistfull # Undernet Extension, Kajetan@Hinner.com, 17/10/98
210479 : secureonlychannel # pircd
211### TODO: see above todo
212### 479 : linkfail # UnrealIrcd, Hendrik Frenzel
213480 : cannotknock # UnrealIrcd, Hendrik Frenzel
214481 : noprivileges
215482 : chanoprivsneeded
216483 : cantkillserver
217484 : ischanservice # Undernet Extension, Kajetan@Hinner.com, 17/10/98
218485 : killdeny # UnrealIrcd, Hendrik Frenzel
219486 : htmdisabled # UnrealIrcd, Hendrik Frenzel
220489 : secureonlychan # UnrealIrcd, Hendrik Frenzel
221491 : nooperhost
222492 : noservicehost
223501 : umodeunknownflag
224502 : usersdontmatch
225511 : silelistfull # Undernet Extension, Kajetan@Hinner.com, 17/10/98
226513 : nosuchgline # Undernet Extension, Kajetan@Hinner.com, 17/10/98
227513 : badping # Undernet Extension, Kajetan@Hinner.com, 17/10/98
228518 : noinvite # UnrealIrcd, Hendrik Frenzel
229519 : admonly # UnrealIrcd, Hendrik Frenzel
230520 : operonly # UnrealIrcd, Hendrik Frenzel
231521 : listsyntax # UnrealIrcd, Hendrik Frenzel
232524 : operspverify # UnrealIrcd, Hendrik Frenzel
233
234600 : rpl_logon # Bahamut IRCD
235601 : rpl_logoff # Bahamut IRCD
236602 : rpl_watchoff # UnrealIrcd, Hendrik Frenzel
237603 : rpl_watchstat # UnrealIrcd, Hendrik Frenzel
238604 : rpl_nowon # Bahamut IRCD
239605 : rpl_nowoff # Bahamut IRCD
240606 : rpl_watchlist # UnrealIrcd, Hendrik Frenzel
241607 : rpl_endofwatchlist # UnrealIrcd, Hendrik Frenzel
242610 : mapmore # UnrealIrcd, Hendrik Frenzel
243640 : rpl_dumping # UnrealIrcd, Hendrik Frenzel
244641 : rpl_dumprpl # UnrealIrcd, Hendrik Frenzel
245642 : rpl_eodump # UnrealIrcd, Hendrik Frenzel
246
247999 : numericerror # Bahamut IRCD
  
1# Represents IRC Users
2module IRC
3
4class 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
25end
26
27end
  
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
8module IRC
9
10module 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
51end
52
53end
  
1
2require 'rif/botbase'
3
4module RIF
5
6class 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
32end
33
34end
  
1
2require 'socket'
3require 'rif/connection'
4require 'rif/event'
5require 'rif/channel'
6require 'rif/user'
7require 'rif/util'
8
9module 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.
13class 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
176end
177
178end
  
1require "rif/user"
2
3module RIF
4
5# Represents an IRC Channel
6class 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
31end
32
33
34end
  
1
2
3
4module RIF
5
6# Handles connection to IRC Server
7class 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
122end
123
124end
  
1require 'yaml'
2
3module RIF
4
5# This is a lookup class for IRC event name mapping
6class 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
13end
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.
20class 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
118end
119
120end
  
1# 001 ne 1 for the purpose of hash keying apparently.
2001 : welcome
3002 : yourhost
4003 : created
5004 : myinfo
6005 : map # Undernet Extension, Kajetan@Hinner.com, 17/11/98
7006 : mapmore # Undernet Extension, Kajetan@Hinner.com, 17/11/98
8007 : mapend # Undernet Extension, Kajetan@Hinner.com, 17/11/98
9008 : snomask # Undernet Extension, Kajetan@Hinner.com, 17/11/98
10009 : statmemtot # Undernet Extension, Kajetan@Hinner.com, 17/11/98
11010 : statmem # Undernet Extension, Kajetan@Hinner.com, 17/11/98
12200 : tracelink
13201 : traceconnecting
14202 : tracehandshake
15203 : traceunknown
16204 : traceoperator
17205 : traceuser
18206 : traceserver
19208 : tracenewtype
20209 : traceclass
21211 : statslinkinfo
22212 : statscommands
23213 : statscline
24214 : statsnline
25215 : statsiline
26216 : statskline
27217 : statsqline
28218 : statsyline
29219 : endofstats
30220 : statsbline # UnrealIrcd, Hendrik Frenzel
31221 : umodeis
32222 : sqline_nick # UnrealIrcd, Hendrik Frenzel
33223 : statsgline # UnrealIrcd, Hendrik Frenzel
34224 : statstline # UnrealIrcd, Hendrik Frenzel
35225 : statseline # UnrealIrcd, Hendrik Frenzel
36226 : statsnline # UnrealIrcd, Hendrik Frenzel
37227 : statsvline # UnrealIrcd, Hendrik Frenzel
38231 : serviceinfo
39232 : endofservices
40233 : service
41234 : servlist
42235 : servlistend
43241 : statslline
44242 : statsuptime
45243 : statsoline
46244 : statshline
47245 : statssline # Reserved, Kajetan@Hinner.com, 17/10/98
48246 : statstline # Undernet Extension, Kajetan@Hinner.com, 17/10/98
49247 : 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
52248 : statsuline # Undernet Extension, Kajetan@Hinner.com, 17/10/98
53249 : statsdebug # Unspecific Extension, Kajetan@Hinner.com, 17/10/98
54250 : luserconns # 1998-03-15 -- tkil
55251 : luserclient
56252 : luserop
57253 : luserunknown
58254 : luserchannels
59255 : luserme
60256 : adminme
61257 : adminloc1
62258 : adminloc2
63259 : adminemail
64261 : tracelog
65262 : endoftrace # 1997-11-24 -- archon
66265 : n_local # 1997-10-16 -- tkil
67266 : n_global # 1997-10-16 -- tkil
68271 : silelist # Undernet Extension, Kajetan@Hinner.com, 17/10/98
69272 : endofsilelist # Undernet Extension, Kajetan@Hinner.com, 17/10/98
70275 : statsdline # Undernet Extension, Kajetan@Hinner.com, 17/10/98
71280 : glist # Undernet Extension, Kajetan@Hinner.com, 17/10/98
72281 : endofglist # Undernet Extension, Kajetan@Hinner.com, 17/10/98
73290 : helphdr # UnrealIrcd, Hendrik Frenzel
74291 : helpop # UnrealIrcd, Hendrik Frenzel
75292 : helptlr # UnrealIrcd, Hendrik Frenzel
76293 : helphlp # UnrealIrcd, Hendrik Frenzel
77294 : helpfwd # UnrealIrcd, Hendrik Frenzel
78295 : helpign # UnrealIrcd, Hendrik Frenzel
79300 : none
80301 : away
81302 : userhost
82303 : ison
83304 : rpl_text # Bahamut IRCD
84305 : unaway
85306 : nowaway
86307 : userip # Undernet Extension, Kajetan@Hinner.com, 17/10/98
87308 : rulesstart # UnrealIrcd, Hendrik Frenzel
88309 : endofrules # UnrealIrcd, Hendrik Frenzel
89310 : whoishelp # (July01-01)Austnet Extension, found by Andypoo <andypoo@secret.com.au>
90311 : whoisuser
91312 : whoisserver
92313 : whoisoperator
93314 : whowasuser
94315 : endofwho
95316 : whoischanop
96317 : whoisidle
97318 : endofwhois
98319 : whoischannels
99320 : whoisvworld # (July01-01)Austnet Extension, found by Andypoo <andypoo@secret.com.au>
100321 : liststart
101322 : list
102323 : listend
103324 : channelmodeis
104329 : channelcreate # 1997-11-24 -- archon
105331 : notopic
106332 : topic
107333 : topicinfo # 1997-11-24 -- archon
108334 : listusage # Undernet Extension, Kajetan@Hinner.com, 17/10/98
109335 : whoisbot # UnrealIrcd, Hendrik Frenzel
110341 : inviting
111342 : summoning
112346 : invitelist # UnrealIrcd, Hendrik Frenzel
113347 : endofinvitelist # UnrealIrcd, Hendrik Frenzel
114348 : exlist # UnrealIrcd, Hendrik Frenzel
115349 : endofexlist # UnrealIrcd, Hendrik Frenzel
116351 : version
117352 : whoreply
118353 : namreply
119354 : whospcrpl # Undernet Extension, Kajetan@Hinner.com, 17/10/98
120361 : killdone
121362 : closing
122363 : closeend
123364 : links
124365 : endoflinks
125366 : endofnames
126367 : banlist
127368 : endofbanlist
128369 : endofwhowas
129371 : info
130372 : motd
131373 : infostart
132374 : endofinfo
133375 : motdstart
134376 : endofmotd
135377 : motd2 # 1997-10-16 -- tkil
136378 : austmotd # (July01-01)Austnet Extension, found by Andypoo <andypoo@secret.com.au>
137379 : whoismodes # UnrealIrcd, Hendrik Frenzel
138381 : youreoper
139382 : rehashing
140383 : youreservice # UnrealIrcd, Hendrik Frenzel
141384 : myportis
142385 : notoperanymore # Unspecific Extension, Kajetan@Hinner.com, 17/10/98
143386 : qlist # UnrealIrcd, Hendrik Frenzel
144387 : endofqlist # UnrealIrcd, Hendrik Frenzel
145388 : alist # UnrealIrcd, Hendrik Frenzel
146389 : endofalist # UnrealIrcd, Hendrik Frenzel
147391 : time
148392 : usersstart
149393 : users
150394 : endofusers
151395 : nousers
152401 : nosuchnick
153402 : nosuchserver
154403 : nosuchchannel
155404 : cannotsendtochan
156405 : toomanychannels
157406 : wasnosuchnick
158407 : toomanytargets
159408 : nosuchservice # UnrealIrcd, Hendrik Frenzel
160409 : noorigin
161411 : norecipient
162412 : notexttosend
163413 : notoplevel
164414 : wildtoplevel
165416 : querytoolong # Undernet Extension, Kajetan@Hinner.com, 17/10/98
166421 : unknowncommand
167422 : nomotd
168423 : noadmininfo
169424 : fileerror
170425 : noopermotd # UnrealIrcd, Hendrik Frenzel
171431 : nonicknamegiven
172432 : erroneusnickname # This iz how its speld in thee RFC.
173433 : nicknameinuse
174434 : norules # UnrealIrcd, Hendrik Frenzel
175435 : serviceconfused # UnrealIrcd, Hendrik Frenzel
176436 : nickcollision
177437 : bannickchange # Undernet Extension, Kajetan@Hinner.com, 17/10/98
178438 : nicktoofast # Undernet Extension, Kajetan@Hinner.com, 17/10/98
179439 : targettoofast # Undernet Extension, Kajetan@Hinner.com, 17/10/98
180440 : servicesdown # Bahamut IRCD
181441 : usernotinchannel
182442 : notonchannel
183443 : useronchannel
184444 : nologin
185445 : summondisabled
186446 : usersdisabled
187447 : nonickchange # UnrealIrcd, Hendrik Frenzel
188451 : notregistered
189455 : hostilename # UnrealIrcd, Hendrik Frenzel
190459 : nohiding # UnrealIrcd, Hendrik Frenzel
191460 : notforhalfops # UnrealIrcd, Hendrik Frenzel
192461 : needmoreparams
193462 : alreadyregistered
194463 : nopermforhost
195464 : passwdmismatch
196465 : yourebannedcreep # I love this one...
197466 : youwillbebanned
198467 : keyset
199468 : invalidusername # Undernet Extension, Kajetan@Hinner.com, 17/10/98
200469 : linkset # UnrealIrcd, Hendrik Frenzel
201470 : linkchannel # UnrealIrcd, Hendrik Frenzel
202471 : channelisfull
203472 : unknownmode
204473 : inviteonlychan
205474 : bannedfromchan
206475 : badchannelkey
207476 : badchanmask
208477 : needreggednick # Bahamut IRCD
209478 : banlistfull # Undernet Extension, Kajetan@Hinner.com, 17/10/98
210479 : secureonlychannel # pircd
211### TODO: see above todo
212### 479 : linkfail # UnrealIrcd, Hendrik Frenzel
213480 : cannotknock # UnrealIrcd, Hendrik Frenzel
214481 : noprivileges
215482 : chanoprivsneeded
216483 : cantkillserver
217484 : ischanservice # Undernet Extension, Kajetan@Hinner.com, 17/10/98
218485 : killdeny # UnrealIrcd, Hendrik Frenzel
219486 : htmdisabled # UnrealIrcd, Hendrik Frenzel
220489 : secureonlychan # UnrealIrcd, Hendrik Frenzel
221491 : nooperhost
222492 : noservicehost
223501 : umodeunknownflag
224502 : usersdontmatch
225511 : silelistfull # Undernet Extension, Kajetan@Hinner.com, 17/10/98
226513 : nosuchgline # Undernet Extension, Kajetan@Hinner.com, 17/10/98
227513 : badping # Undernet Extension, Kajetan@Hinner.com, 17/10/98
228518 : noinvite # UnrealIrcd, Hendrik Frenzel
229519 : admonly # UnrealIrcd, Hendrik Frenzel
230520 : operonly # UnrealIrcd, Hendrik Frenzel
231521 : listsyntax # UnrealIrcd, Hendrik Frenzel
232524 : operspverify # UnrealIrcd, Hendrik Frenzel
233
234600 : rpl_logon # Bahamut IRCD
235601 : rpl_logoff # Bahamut IRCD
236602 : rpl_watchoff # UnrealIrcd, Hendrik Frenzel
237603 : rpl_watchstat # UnrealIrcd, Hendrik Frenzel
238604 : rpl_nowon # Bahamut IRCD
239605 : rpl_nowoff # Bahamut IRCD
240606 : rpl_watchlist # UnrealIrcd, Hendrik Frenzel
241607 : rpl_endofwatchlist # UnrealIrcd, Hendrik Frenzel
242610 : mapmore # UnrealIrcd, Hendrik Frenzel
243640 : rpl_dumping # UnrealIrcd, Hendrik Frenzel
244641 : rpl_dumprpl # UnrealIrcd, Hendrik Frenzel
245642 : rpl_eodump # UnrealIrcd, Hendrik Frenzel
246
247999 : numericerror # Bahamut IRCD
  
1# Represents IRC Users
2module RIF
3
4class 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
25end
26
27end
  
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
8module RIF
9
10module 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
51end
52
53end
  
11
22
3PROJECT_NAME = PKG_NAME = 'rubyirc'
3PROJECT_NAME = PKG_NAME = 'rif'
44
5PKG_VERSION = "1.9"
5PKG_VERSION = "0.1"
66PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
77
88def get_files(dir)
1919desc 'Generate RDoc'
2020rd = Rake::RDocTask.new do |rdoc|
2121 rdoc.rdoc_dir = 'doc/output/rdoc'
22 rdoc.options << '--title' << 'Docurb' << '--line-numbers' <<
22 rdoc.options << '--title' << 'Ruby IRC Framework' << '--line-numbers' <<
2323 '--inline-source' << '--accessor' << 'delegate' << '--main' << 'README'
2424# rdoc.rdoc_files.include('README', 'CHANGES', 'LGPL-LICENSE', 'lib/**/*.rb')
2525end
2929 s.version = PKG_VERSION
3030 s.summary = 'Application to read/browse ruby documentation'
3131 s.description = <<-end_description
32 Application to read/browse ruby documentation
32 Ruby IRC Framework
3333 end_description
3434
35
36
3735 s.files = FileList[
3836 '[A-Z]*',
39 'lib/irc/*.rb',
40 'lib/irc/eventmap.yml',
37 'lib/rif/*.rb',
38 'lib/rif/eventmap.yml',
4139 'examples/*.rb'
4240 ].to_a
4341
44 s.autorequire = 'rubyirc'
42 s.autorequire = 'rif'
4543 s.author = ["David A. Cuadrado"]
4644 s.email = "krawek@gmail.com"
47 s.homepage = "http://gitorious.org/projects/rubyirc"
45 s.homepage = "http://gitorious.org/projects/ruby-irc"
4846# s.rubyforge_project = "???"
4947end
5048
5353end
5454
5555desc "Publish #{PKG_NAME} packages on RubyForge"
56task :publish_ruby_irc_packages => [:verify_user, :package] do
56task :publish_packages => [:verify_user, :package] do
5757 release_files = FileList[
5858 "pkg/#{PKG_FILE_NAME}.gem",
5959 "pkg/#{PKG_FILE_NAME}.tgz",
6565 Rake::XForge::Release.new(MetaProject::Project::XForge::RubyForge.new(PROJECT_NAME)) do |xf|
6666 xf.user_name = ENV['RUBYFORGE_USER']
6767 xf.files = release_files.to_a
68 xf.release_name = "rubyirc #{PKG_VERSION}"
68 xf.release_name = "rif #{PKG_VERSION}"
6969 end
7070end