Ruby-IRC 1.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/README +18 -0
- data/lib/IRC.rb +121 -0
- data/lib/IRCChannel.rb +24 -0
- data/lib/IRCConnection.rb +53 -0
- data/lib/IRCEvent.rb +340 -0
- data/lib/IRCUser.rb +20 -0
- metadata +50 -0
data/README
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
# = Ruby-IRC
|
2
|
+
# Framework for IRC clients
|
3
|
+
# == What is it?
|
4
|
+
# Ruby-IRC is a simple framework for creating clients for IRC. It will
|
5
|
+
# monitor multiple IO sockets for data. Allows user defined handlers
|
6
|
+
# for IRC events.
|
7
|
+
#
|
8
|
+
# == A simple usage example
|
9
|
+
#
|
10
|
+
# bot = IRC.new("Nickname", "server.example.com", "6667", [ "#arrayofchannels"])
|
11
|
+
# IRCEvent.add_callback('endofmotd') { |event| bot.add_channel('#eris') }
|
12
|
+
# IRCEvent.add_callback('join') {|event|
|
13
|
+
# bot.send_message(event.channel, "Hello #{event.from}")
|
14
|
+
# }
|
15
|
+
# bot.connect
|
16
|
+
# == Author
|
17
|
+
# Chris Boyer
|
18
|
+
# email: cboyer@musiciansfriend.com
|
data/lib/IRC.rb
ADDED
@@ -0,0 +1,121 @@
|
|
1
|
+
|
2
|
+
require 'socket'
|
3
|
+
require 'IRCConnection'
|
4
|
+
require 'IRCEvent'
|
5
|
+
require 'IRCChannel'
|
6
|
+
require 'IRCUser'
|
7
|
+
|
8
|
+
|
9
|
+
|
10
|
+
# Class IRC is a master class that handles connection to the irc
|
11
|
+
# server and pasring of IRC events, through the IRCEvent class.
|
12
|
+
|
13
|
+
class IRC
|
14
|
+
@channels = nil
|
15
|
+
# Create a new IRC Object instance
|
16
|
+
def initialize( nick, server, port, realname='RBot')
|
17
|
+
@nick = nick
|
18
|
+
@server = server
|
19
|
+
@port = port
|
20
|
+
@realname = realname
|
21
|
+
@channels = Array.new(0)
|
22
|
+
# Some good default Event handlers. These can and will be overridden by users.
|
23
|
+
# Thses make changes on the IRCbot object. So they need to be here.
|
24
|
+
|
25
|
+
# Topic events can come on two tags, so we create on proc to handle them.
|
26
|
+
|
27
|
+
topic_proc = Proc.new { |event|
|
28
|
+
self.channels.each { |chan|
|
29
|
+
puts "Examine channel #{chan.name} for #{event.channel}"
|
30
|
+
if chan == event.channel
|
31
|
+
puts "Setting topic: #{event.message}"
|
32
|
+
chan.topic = event.message
|
33
|
+
end
|
34
|
+
}
|
35
|
+
}
|
36
|
+
|
37
|
+
IRCEvent.add_handler('332', topic_proc)
|
38
|
+
IRCEvent.add_handler('topic', topic_proc)
|
39
|
+
|
40
|
+
|
41
|
+
end
|
42
|
+
attr_reader :nick, :server, :port
|
43
|
+
# Join a channel, adding it to the list of joined channels
|
44
|
+
def add_channel channel
|
45
|
+
join(channel)
|
46
|
+
self
|
47
|
+
end
|
48
|
+
# Returns a list of channels joined
|
49
|
+
def channels
|
50
|
+
@channels
|
51
|
+
end
|
52
|
+
# Alias for IRC.connect
|
53
|
+
def start
|
54
|
+
self.connect
|
55
|
+
end
|
56
|
+
# Open a connection to the server using the IRC Connect
|
57
|
+
# method. Events yielded from the IRCConnection handler are
|
58
|
+
# processed and then control is returned to IRCConnection
|
59
|
+
def connect
|
60
|
+
IRCConnection.handle_connection(@server, @port) do
|
61
|
+
IRCConnection.send_to_server "NICK #{@nick}"
|
62
|
+
IRCConnection.send_to_server "USER #{@nick} 8 * :#{@realname}"
|
63
|
+
IRCConnection.main do |event|
|
64
|
+
event.process
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
# Joins a channel on a server.
|
69
|
+
def join(channel)
|
70
|
+
if (IRCConnection.send_to_server("JOIN #{channel}"))
|
71
|
+
@channels.push(IRCChannel.new(channel));
|
72
|
+
end
|
73
|
+
end
|
74
|
+
# Leaves a channel on a server
|
75
|
+
def part(channel)
|
76
|
+
if (IRCConnection.send_to_server("PART #{channel}"))
|
77
|
+
@channels.delete_if {|chan| chan.name == channel }
|
78
|
+
end
|
79
|
+
end
|
80
|
+
# Sends a private message, or channel message
|
81
|
+
def send_message(to, message)
|
82
|
+
IRCConnection.send_to_server("privmsg #{to} : #{message}");
|
83
|
+
end
|
84
|
+
# Sends a notice
|
85
|
+
def send_notice(to, message)
|
86
|
+
IRCConnection.send_to_server("NOTICE #{to} : #{message}");
|
87
|
+
end
|
88
|
+
# Lights, camera, action
|
89
|
+
def send_action(to, action)
|
90
|
+
send_ctcp(to, 'ACTION', action);
|
91
|
+
end
|
92
|
+
# And now, to send CTCP
|
93
|
+
def send_ctcp(to, type, message)
|
94
|
+
IRCConnection.send_to_server("privmsg #{to} :\001#{type} #{message}");
|
95
|
+
end
|
96
|
+
# Quits the IRC Server
|
97
|
+
def send_quit
|
98
|
+
IRCConnection.send_to_server("QUIT : Quit ordered by user")
|
99
|
+
end
|
100
|
+
# Ops selected user.
|
101
|
+
def op(channel, user)
|
102
|
+
IRCConnection.send_to_server("MODE #{channel} +o #{user}")
|
103
|
+
end
|
104
|
+
# Changes the current nickname
|
105
|
+
def ch_nick(nick)
|
106
|
+
IRCConnection.send_to_server("NICK #{nick}")
|
107
|
+
@nick = nick
|
108
|
+
end
|
109
|
+
# Removes operator status from a user
|
110
|
+
def deop(channel, user)
|
111
|
+
IRCConnection.send_to_server("MODE #{channel} -o #{user}")
|
112
|
+
end
|
113
|
+
# Changes target users mode
|
114
|
+
def mode(channel, user, mode)
|
115
|
+
IRCConnection.send_to_server("MODE #{channel} #{mode} #{user}")
|
116
|
+
end
|
117
|
+
# Retrievs user information from the server
|
118
|
+
def get_user_info(user)
|
119
|
+
IRCConnection.send_to_server("WHO #{user}")
|
120
|
+
end
|
121
|
+
end
|
data/lib/IRCChannel.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require "IRCUser"
|
2
|
+
|
3
|
+
class IRCChannel
|
4
|
+
def initialize(name)
|
5
|
+
@name = name
|
6
|
+
@users = Array.new(0)
|
7
|
+
end
|
8
|
+
attr_reader :name
|
9
|
+
def topic=(topic)
|
10
|
+
@topic = topic
|
11
|
+
end
|
12
|
+
def topic
|
13
|
+
if @topic
|
14
|
+
return @topic
|
15
|
+
end
|
16
|
+
return "No Topic set"
|
17
|
+
end
|
18
|
+
def add_user(username)
|
19
|
+
@users.push(IRCUser.create_user(username))
|
20
|
+
end
|
21
|
+
def users
|
22
|
+
@users
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
|
2
|
+
# Handles connection to IRC Server
|
3
|
+
class IRCConnection
|
4
|
+
@@quit = 0
|
5
|
+
@@readsockets = Array.new(0)
|
6
|
+
@@events = Hash.new()
|
7
|
+
# Creates a socket connection and then yields.
|
8
|
+
def IRCConnection.handle_connection(server, port)
|
9
|
+
@@server = server
|
10
|
+
@@port = port
|
11
|
+
@@socket = TCPsocket.open(server, port)
|
12
|
+
add_IO_socket(@@socket) {|sock| IRCEvent.new(sock.readline.chomp) }
|
13
|
+
yield
|
14
|
+
@@socket.close
|
15
|
+
end
|
16
|
+
# Sends a line of text to the server
|
17
|
+
def IRCConnection.send_to_server(line)
|
18
|
+
@@socket.write(line + "\n")
|
19
|
+
end
|
20
|
+
# This loop monitors all IO_Sockets IRCConnection controls
|
21
|
+
# (including the IRC socket) and yields events to the IO_Sockets
|
22
|
+
# event handler.
|
23
|
+
def IRCConnection.main
|
24
|
+
while(@@quit == 0)
|
25
|
+
do_one_loop { |event|
|
26
|
+
yield event
|
27
|
+
}
|
28
|
+
end
|
29
|
+
end
|
30
|
+
# Makes one single loop pass, checking all sockets for data to read,
|
31
|
+
# and yields the data to the sockets event handler.
|
32
|
+
def IRCConnection.do_one_loop
|
33
|
+
read_sockets = select(@@readsockets, nil, nil, nil);
|
34
|
+
read_sockets[0].each {|sock|
|
35
|
+
yield @@events[sock.to_i].call(sock)
|
36
|
+
}
|
37
|
+
end
|
38
|
+
# Ends connection to the irc server
|
39
|
+
def IRCConnection.quit
|
40
|
+
@@quit = 1
|
41
|
+
end
|
42
|
+
# Retrieves user info from the server
|
43
|
+
def IRCConnection.get_user_info(user)
|
44
|
+
IRCConnection.send_to_server("WHOIS #{user}")
|
45
|
+
end
|
46
|
+
def IRCConnection.add_IO_socket(socket, &event_generator)
|
47
|
+
# Adds a new socket to the list of sockets to monitor for new data.
|
48
|
+
@@readsockets.push(socket)
|
49
|
+
@@events[socket.to_i] = event_generator
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
|
data/lib/IRCEvent.rb
ADDED
@@ -0,0 +1,340 @@
|
|
1
|
+
|
2
|
+
# This is a lookup class for IRC event name mapping
|
3
|
+
class EventLookup
|
4
|
+
@@lookup = Hash[
|
5
|
+
# suck! these aren't treated as strings --
|
6
|
+
# 001 ne 1 for the purpose of hash keying, apparently.
|
7
|
+
'001' => "welcome",
|
8
|
+
'002' => "yourhost",
|
9
|
+
'003' => "created",
|
10
|
+
'004' => "myinfo",
|
11
|
+
'005' => "map", # Undernet Extension, Kajetan@Hinner.com, 17/11/98
|
12
|
+
'006' => "mapmore", # Undernet Extension, Kajetan@Hinner.com, 17/11/98
|
13
|
+
'007' => "mapend", # Undernet Extension, Kajetan@Hinner.com, 17/11/98
|
14
|
+
|
15
|
+
'008' => "snomask", # Undernet Extension, Kajetan@Hinner.com, 17/11/98
|
16
|
+
|
17
|
+
'009' => "statmemtot", # Undernet Extension, Kajetan@Hinner.com, 17/11/98
|
18
|
+
|
19
|
+
'010' => "statmem", # Undernet Extension, Kajetan@Hinner.com, 17/11/98
|
20
|
+
|
21
|
+
|
22
|
+
'200' => "tracelink",
|
23
|
+
'201' => "traceconnecting",
|
24
|
+
'202' => "tracehandshake",
|
25
|
+
'203' => "traceunknown",
|
26
|
+
'204' => "traceoperator",
|
27
|
+
'205' => "traceuser",
|
28
|
+
'206' => "traceserver",
|
29
|
+
'208' => "tracenewtype",
|
30
|
+
'209' => "traceclass",
|
31
|
+
'211' => "statslinkinfo",
|
32
|
+
'212' => "statscommands",
|
33
|
+
'213' => "statscline",
|
34
|
+
'214' => "statsnline",
|
35
|
+
'215' => "statsiline",
|
36
|
+
'216' => "statskline",
|
37
|
+
'217' => "statsqline",
|
38
|
+
'218' => "statsyline",
|
39
|
+
'219' => "endofstats",
|
40
|
+
'220' => "statsbline", # UnrealIrcd, Hendrik Frenzel
|
41
|
+
'221' => "umodeis",
|
42
|
+
'222' => "sqline_nick", # UnrealIrcd, Hendrik Frenzel
|
43
|
+
'223' => "statsgline", # UnrealIrcd, Hendrik Frenzel
|
44
|
+
'224' => "statstline", # UnrealIrcd, Hendrik Frenzel
|
45
|
+
'225' => "statseline", # UnrealIrcd, Hendrik Frenzel
|
46
|
+
'226' => "statsnline", # UnrealIrcd, Hendrik Frenzel
|
47
|
+
'227' => "statsvline", # UnrealIrcd, Hendrik Frenzel
|
48
|
+
'231' => "serviceinfo",
|
49
|
+
'232' => "endofservices",
|
50
|
+
'233' => "service",
|
51
|
+
'234' => "servlist",
|
52
|
+
'235' => "servlistend",
|
53
|
+
'241' => "statslline",
|
54
|
+
'242' => "statsuptime",
|
55
|
+
'243' => "statsoline",
|
56
|
+
'244' => "statshline",
|
57
|
+
'245' => "statssline", # Reserved, Kajetan@Hinner.com, 17/10/98
|
58
|
+
'246' => "statstline", # Undernet Extension, Kajetan@Hinner.com, 17/10/98
|
59
|
+
'247' => "statsgline", # Undernet Extension, Kajetan@Hinner.com, 17/10/98
|
60
|
+
### TODO: need numerics to be able to map to multiple strings
|
61
|
+
### 247' => "statsxline", # UnrealIrcd, Hendrik Frenzel
|
62
|
+
'248' => "statsuline", # Undernet Extension, Kajetan@Hinner.com, 17/10/98
|
63
|
+
'249' => "statsdebug", # Unspecific Extension, Kajetan@Hinner.com, 17/10/98
|
64
|
+
'250' => "luserconns", # 1998-03-15 -- tkil
|
65
|
+
'251' => "luserclient",
|
66
|
+
'252' => "luserop",
|
67
|
+
'253' => "luserunknown",
|
68
|
+
'254' => "luserchannels",
|
69
|
+
'255' => "luserme",
|
70
|
+
'256' => "adminme",
|
71
|
+
'257' => "adminloc1",
|
72
|
+
'258' => "adminloc2",
|
73
|
+
'259' => "adminemail",
|
74
|
+
'261' => "tracelog",
|
75
|
+
'262' => "endoftrace", # 1997-11-24 -- archon
|
76
|
+
'265' => "n_local", # 1997-10-16 -- tkil
|
77
|
+
'266' => "n_global", # 1997-10-16 -- tkil
|
78
|
+
'271' => "silelist", # Undernet Extension, Kajetan@Hinner.com, 17/10/98
|
79
|
+
'272' => "endofsilelist", # Undernet Extension, Kajetan@Hinner.com, 17/10/98
|
80
|
+
'275' => "statsdline", # Undernet Extension, Kajetan@Hinner.com, 17/10/98
|
81
|
+
'280' => "glist", # Undernet Extension, Kajetan@Hinner.com, 17/10/98
|
82
|
+
'281' => "endofglist", # Undernet Extension, Kajetan@Hinner.com, 17/10/98
|
83
|
+
'290' => "helphdr", # UnrealIrcd, Hendrik Frenzel
|
84
|
+
'291' => "helpop", # UnrealIrcd, Hendrik Frenzel
|
85
|
+
'292' => "helptlr", # UnrealIrcd, Hendrik Frenzel
|
86
|
+
'293' => "helphlp", # UnrealIrcd, Hendrik Frenzel
|
87
|
+
'294' => "helpfwd", # UnrealIrcd, Hendrik Frenzel
|
88
|
+
'295' => "helpign", # UnrealIrcd, Hendrik Frenzel
|
89
|
+
|
90
|
+
'300' => "none",
|
91
|
+
'301' => "away",
|
92
|
+
'302' => "userhost",
|
93
|
+
'303' => "ison",
|
94
|
+
'304' => "rpl_text", # Bahamut IRCD
|
95
|
+
'305' => "unaway",
|
96
|
+
'306' => "nowaway",
|
97
|
+
'307' => "userip", # Undernet Extension, Kajetan@Hinner.com, 17/10/98
|
98
|
+
'308' => "rulesstart", # UnrealIrcd, Hendrik Frenzel
|
99
|
+
'309' => "endofrules", # UnrealIrcd, Hendrik Frenzel
|
100
|
+
'310' => "whoishelp", # (July01-01)Austnet Extension, found by Andypoo <andypoo@secret.com.au>
|
101
|
+
'311' => "whoisuser",
|
102
|
+
'312' => "whoisserver",
|
103
|
+
'313' => "whoisoperator",
|
104
|
+
'314' => "whowasuser",
|
105
|
+
'315' => "endofwho",
|
106
|
+
'316' => "whoischanop",
|
107
|
+
'317' => "whoisidle",
|
108
|
+
'318' => "endofwhois",
|
109
|
+
'319' => "whoischannels",
|
110
|
+
'320' => "whoisvworld", # (July01-01)Austnet Extension, found by Andypoo <andypoo@secret.com.au>
|
111
|
+
'321' => "liststart",
|
112
|
+
'322' => "list",
|
113
|
+
'323' => "listend",
|
114
|
+
'324' => "channelmodeis",
|
115
|
+
'329' => "channelcreate", # 1997-11-24 -- archon
|
116
|
+
'331' => "notopic",
|
117
|
+
'332' => "topic",
|
118
|
+
'333' => "topicinfo", # 1997-11-24 -- archon
|
119
|
+
'334' => "listusage", # Undernet Extension, Kajetan@Hinner.com, 17/10/98
|
120
|
+
'335' => "whoisbot", # UnrealIrcd, Hendrik Frenzel
|
121
|
+
'341' => "inviting",
|
122
|
+
'342' => "summoning",
|
123
|
+
'346' => "invitelist", # UnrealIrcd, Hendrik Frenzel
|
124
|
+
'347' => "endofinvitelist", # UnrealIrcd, Hendrik Frenzel
|
125
|
+
'348' => "exlist", # UnrealIrcd, Hendrik Frenzel
|
126
|
+
'349' => "endofexlist", # UnrealIrcd, Hendrik Frenzel
|
127
|
+
'351' => "version",
|
128
|
+
'352' => "whoreply",
|
129
|
+
'353' => "namreply",
|
130
|
+
'354' => "whospcrpl", # Undernet Extension, Kajetan@Hinner.com, 17/10/98
|
131
|
+
'361' => "killdone",
|
132
|
+
'362' => "closing",
|
133
|
+
'363' => "closeend",
|
134
|
+
'364' => "links",
|
135
|
+
'365' => "endoflinks",
|
136
|
+
'366' => "endofnames",
|
137
|
+
'367' => "banlist",
|
138
|
+
'368' => "endofbanlist",
|
139
|
+
'369' => "endofwhowas",
|
140
|
+
'371' => "info",
|
141
|
+
'372' => "motd",
|
142
|
+
'373' => "infostart",
|
143
|
+
'374' => "endofinfo",
|
144
|
+
'375' => "motdstart",
|
145
|
+
'376' => "endofmotd",
|
146
|
+
'377' => "motd2", # 1997-10-16 -- tkil
|
147
|
+
'378' => "austmotd", # (July01-01)Austnet Extension, found by Andypoo <andypoo@secret.com.au>
|
148
|
+
'379' => "whoismodes", # UnrealIrcd, Hendrik Frenzel
|
149
|
+
'381' => "youreoper",
|
150
|
+
'382' => "rehashing",
|
151
|
+
'383' => "youreservice", # UnrealIrcd, Hendrik Frenzel
|
152
|
+
'384' => "myportis",
|
153
|
+
'385' => "notoperanymore", # Unspecific Extension, Kajetan@Hinner.com, 17/10/98
|
154
|
+
'386' => "qlist", # UnrealIrcd, Hendrik Frenzel
|
155
|
+
'387' => "endofqlist", # UnrealIrcd, Hendrik Frenzel
|
156
|
+
'388' => "alist", # UnrealIrcd, Hendrik Frenzel
|
157
|
+
'389' => "endofalist", # UnrealIrcd, Hendrik Frenzel
|
158
|
+
'391' => "time",
|
159
|
+
'392' => "usersstart",
|
160
|
+
'393' => "users",
|
161
|
+
'394' => "endofusers",
|
162
|
+
'395' => "nousers",
|
163
|
+
|
164
|
+
'401' => "nosuchnick",
|
165
|
+
'402' => "nosuchserver",
|
166
|
+
'403' => "nosuchchannel",
|
167
|
+
'404' => "cannotsendtochan",
|
168
|
+
'405' => "toomanychannels",
|
169
|
+
'406' => "wasnosuchnick",
|
170
|
+
'407' => "toomanytargets",
|
171
|
+
'408' => "nosuchservice", # UnrealIrcd, Hendrik Frenzel
|
172
|
+
'409' => "noorigin",
|
173
|
+
'411' => "norecipient",
|
174
|
+
'412' => "notexttosend",
|
175
|
+
'413' => "notoplevel",
|
176
|
+
'414' => "wildtoplevel",
|
177
|
+
'416' => "querytoolong", # Undernet Extension, Kajetan@Hinner.com, 17/10/98
|
178
|
+
'421' => "unknowncommand",
|
179
|
+
'422' => "nomotd",
|
180
|
+
'423' => "noadmininfo",
|
181
|
+
'424' => "fileerror",
|
182
|
+
'425' => "noopermotd", # UnrealIrcd, Hendrik Frenzel
|
183
|
+
'431' => "nonicknamegiven",
|
184
|
+
'432' => "erroneusnickname", # This iz how its speld in thee RFC.
|
185
|
+
'433' => "nicknameinuse",
|
186
|
+
'434' => "norules", # UnrealIrcd, Hendrik Frenzel
|
187
|
+
'435' => "serviceconfused", # UnrealIrcd, Hendrik Frenzel
|
188
|
+
'436' => "nickcollision",
|
189
|
+
'437' => "bannickchange", # Undernet Extension, Kajetan@Hinner.com, 17/10/98
|
190
|
+
'438' => "nicktoofast", # Undernet Extension, Kajetan@Hinner.com, 17/10/98
|
191
|
+
'439' => "targettoofast", # Undernet Extension, Kajetan@Hinner.com, 17/10/98
|
192
|
+
'440' => "servicesdown", # Bahamut IRCD
|
193
|
+
'441' => "usernotinchannel",
|
194
|
+
'442' => "notonchannel",
|
195
|
+
'443' => "useronchannel",
|
196
|
+
'444' => "nologin",
|
197
|
+
'445' => "summondisabled",
|
198
|
+
'446' => "usersdisabled",
|
199
|
+
'447' => "nonickchange", # UnrealIrcd, Hendrik Frenzel
|
200
|
+
'451' => "notregistered",
|
201
|
+
'455' => "hostilename", # UnrealIrcd, Hendrik Frenzel
|
202
|
+
'459' => "nohiding", # UnrealIrcd, Hendrik Frenzel
|
203
|
+
'460' => "notforhalfops", # UnrealIrcd, Hendrik Frenzel
|
204
|
+
'461' => "needmoreparams",
|
205
|
+
'462' => "alreadyregistered",
|
206
|
+
'463' => "nopermforhost",
|
207
|
+
'464' => "passwdmismatch",
|
208
|
+
'465' => "yourebannedcreep", # I love this one...
|
209
|
+
'466' => "youwillbebanned",
|
210
|
+
'467' => "keyset",
|
211
|
+
'468' => "invalidusername", # Undernet Extension, Kajetan@Hinner.com, 17/10/98
|
212
|
+
'469' => "linkset", # UnrealIrcd, Hendrik Frenzel
|
213
|
+
'470' => "linkchannel", # UnrealIrcd, Hendrik Frenzel
|
214
|
+
'471' => "channelisfull",
|
215
|
+
'472' => "unknownmode",
|
216
|
+
'473' => "inviteonlychan",
|
217
|
+
'474' => "bannedfromchan",
|
218
|
+
'475' => "badchannelkey",
|
219
|
+
'476' => "badchanmask",
|
220
|
+
'477' => "needreggednick", # Bahamut IRCD
|
221
|
+
'478' => "banlistfull", # Undernet Extension, Kajetan@Hinner.com, 17/10/98
|
222
|
+
'479' => "secureonlychannel", # pircd
|
223
|
+
### TODO: see above todo
|
224
|
+
### 479' => "linkfail", # UnrealIrcd, Hendrik Frenzel
|
225
|
+
'480' => "cannotknock", # UnrealIrcd, Hendrik Frenzel
|
226
|
+
'481' => "noprivileges",
|
227
|
+
'482' => "chanoprivsneeded",
|
228
|
+
'483' => "cantkillserver",
|
229
|
+
'484' => "ischanservice", # Undernet Extension, Kajetan@Hinner.com, 17/10/98
|
230
|
+
'485' => "killdeny", # UnrealIrcd, Hendrik Frenzel
|
231
|
+
'486' => "htmdisabled", # UnrealIrcd, Hendrik Frenzel
|
232
|
+
'489' => "secureonlychan", # UnrealIrcd, Hendrik Frenzel
|
233
|
+
'491' => "nooperhost",
|
234
|
+
'492' => "noservicehost",
|
235
|
+
|
236
|
+
'501' => "umodeunknownflag",
|
237
|
+
'502' => "usersdontmatch",
|
238
|
+
'511' => "silelistfull", # Undernet Extension, Kajetan@Hinner.com, 17/10/98
|
239
|
+
'513' => "nosuchgline", # Undernet Extension, Kajetan@Hinner.com, 17/10/98
|
240
|
+
'513' => "badping", # Undernet Extension, Kajetan@Hinner.com, 17/10/98
|
241
|
+
'518' => "noinvite", # UnrealIrcd, Hendrik Frenzel
|
242
|
+
'519' => "admonly", # UnrealIrcd, Hendrik Frenzel
|
243
|
+
'520' => "operonly", # UnrealIrcd, Hendrik Frenzel
|
244
|
+
'521' => "listsyntax", # UnrealIrcd, Hendrik Frenzel
|
245
|
+
'524' => "operspverify", # UnrealIrcd, Hendrik Frenzel
|
246
|
+
|
247
|
+
'600' => "rpl_logon", # Bahamut IRCD
|
248
|
+
'601' => "rpl_logoff", # Bahamut IRCD
|
249
|
+
'602' => "rpl_watchoff", # UnrealIrcd, Hendrik Frenzel
|
250
|
+
'603' => "rpl_watchstat", # UnrealIrcd, Hendrik Frenzel
|
251
|
+
'604' => "rpl_nowon", # Bahamut IRCD
|
252
|
+
'605' => "rpl_nowoff", # Bahamut IRCD
|
253
|
+
'606' => "rpl_watchlist", # UnrealIrcd, Hendrik Frenzel
|
254
|
+
'607' => "rpl_endofwatchlist", # UnrealIrcd, Hendrik Frenzel
|
255
|
+
'610' => "mapmore", # UnrealIrcd, Hendrik Frenzel
|
256
|
+
'640' => "rpl_dumping", # UnrealIrcd, Hendrik Frenzel
|
257
|
+
'641' => "rpl_dumprpl", # UnrealIrcd, Hendrik Frenzel
|
258
|
+
'642' => "rpl_eodump", # UnrealIrcd, Hendrik Frenzel
|
259
|
+
|
260
|
+
'999' => "numericerror", # Bahamut IRCD
|
261
|
+
];
|
262
|
+
def EventLookup::find_by_number(num)
|
263
|
+
return @@lookup[num]
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
|
268
|
+
# Handles an IRC generated event.
|
269
|
+
# Handlers are for the IRC framework to use
|
270
|
+
# Callbacks are for users to add.
|
271
|
+
# Both handlers and callbacks can be called for the same event.
|
272
|
+
class IRCEvent
|
273
|
+
@@handlers = { 'ping' => lambda {|event| IRCConnection.send_to_server("PONG #{event.message}") } }
|
274
|
+
@@callbacks = Hash.new()
|
275
|
+
attr_reader :message, :event_type, :from, :channel, :target, :mode, :stats
|
276
|
+
def initialize (line)
|
277
|
+
line.sub!(/^:/, '')
|
278
|
+
mess_parts = line.split(':', 2);
|
279
|
+
# mess_parts[0] is server info
|
280
|
+
# mess_parts[1] is the message that was sent
|
281
|
+
@message = mess_parts[1]
|
282
|
+
@stats = mess_parts[0].scan(/[-\w.\#\@]+/)
|
283
|
+
|
284
|
+
if @stats[0].match(/^PING/)
|
285
|
+
@event_type = 'ping'
|
286
|
+
elsif @stats[1] && @stats[1].match(/^\d+/)
|
287
|
+
@event_type = EventLookup::find_by_number(@stats[1]);
|
288
|
+
@channel = @stats[3]
|
289
|
+
else
|
290
|
+
@event_type = @stats[2].downcase if @stats[2]
|
291
|
+
end
|
292
|
+
|
293
|
+
if @event_type != 'ping'
|
294
|
+
@from = @stats[0]
|
295
|
+
@user = IRCUser.create_user(@from)
|
296
|
+
end
|
297
|
+
@hostmask = @stats[1] if @event_type.eql?('PRIVMSG'.downcase)
|
298
|
+
@channel = @stats[3] if @stats[3] && !@channel
|
299
|
+
@target = @stats[5] if @stats[5]
|
300
|
+
@mode = @stats[4] if @stats[4]
|
301
|
+
|
302
|
+
|
303
|
+
|
304
|
+
# Unfortunatly, not all messages are created equal. This is our
|
305
|
+
# special exceptions section
|
306
|
+
if @event_type == 'join'
|
307
|
+
@channel = @message
|
308
|
+
end
|
309
|
+
|
310
|
+
end
|
311
|
+
# Adds a callback for the specified irc message.
|
312
|
+
def IRCEvent.add_callback(message_id, &callback)
|
313
|
+
@@callbacks[message_id] = callback
|
314
|
+
end
|
315
|
+
# Adds a handler to the handler function hash.
|
316
|
+
def IRCEvent.add_handler(message_id, proc=nil, &handler)
|
317
|
+
if block_given?
|
318
|
+
@@handlers[message_id] = handler
|
319
|
+
elsif proc
|
320
|
+
@@handlers[message_id] = proc
|
321
|
+
end
|
322
|
+
end
|
323
|
+
# Process this event, preforming which ever handler and callback is specified
|
324
|
+
# for this event.
|
325
|
+
def process
|
326
|
+
handled = nil
|
327
|
+
if @@handlers[@event_type]
|
328
|
+
@@handlers[@event_type].call(self)
|
329
|
+
handled = 1
|
330
|
+
end
|
331
|
+
if @@callbacks[@event_type]
|
332
|
+
@@callbacks[@event_type].call(self)
|
333
|
+
handled = 1
|
334
|
+
end
|
335
|
+
if !handled
|
336
|
+
puts "No handler for event type #@event_type in #{self.class}"
|
337
|
+
end
|
338
|
+
end
|
339
|
+
end
|
340
|
+
|
data/lib/IRCUser.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
|
2
|
+
class IRCUser
|
3
|
+
@@users = Hash.new()
|
4
|
+
@modes = Hash.new()
|
5
|
+
def IRCUser.create_user(username)
|
6
|
+
username.sub!(/^[\@\%]/,'')
|
7
|
+
|
8
|
+
if @@users[username]
|
9
|
+
return @@users[username]
|
10
|
+
end
|
11
|
+
@@users[username] = self.new(username)
|
12
|
+
@@users[username]
|
13
|
+
end
|
14
|
+
attr_reader :username, :mask
|
15
|
+
attr_writer :mask
|
16
|
+
private
|
17
|
+
def initialize (username)
|
18
|
+
@username = username
|
19
|
+
end
|
20
|
+
end
|
metadata
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.8.11
|
3
|
+
specification_version: 1
|
4
|
+
name: Ruby-IRC
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: 1.0.3
|
7
|
+
date: 2006-06-08 00:00:00 -07:00
|
8
|
+
summary: An IRC Client library
|
9
|
+
require_paths:
|
10
|
+
- lib
|
11
|
+
email: cboyer@musiciansfriend.com
|
12
|
+
homepage: http://www.pulpreligion.org
|
13
|
+
rubyforge_project:
|
14
|
+
description:
|
15
|
+
autorequire: IRC
|
16
|
+
default_executable:
|
17
|
+
bindir: bin
|
18
|
+
has_rdoc: "true"
|
19
|
+
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">"
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.0.0
|
24
|
+
version:
|
25
|
+
platform: ruby
|
26
|
+
signing_key:
|
27
|
+
cert_chain:
|
28
|
+
authors:
|
29
|
+
- Chris Boyer
|
30
|
+
files:
|
31
|
+
- lib/IRCEvent.rb
|
32
|
+
- lib/IRC.rb
|
33
|
+
- lib/IRCChannel.rb
|
34
|
+
- lib/IRCConnection.rb
|
35
|
+
- lib/IRCUser.rb
|
36
|
+
- README
|
37
|
+
test_files: []
|
38
|
+
|
39
|
+
rdoc_options: []
|
40
|
+
|
41
|
+
extra_rdoc_files:
|
42
|
+
- README
|
43
|
+
executables: []
|
44
|
+
|
45
|
+
extensions: []
|
46
|
+
|
47
|
+
requirements: []
|
48
|
+
|
49
|
+
dependencies: []
|
50
|
+
|