konn-rupircd 0.6.2 → 0.6.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/VERSION +1 -1
- data/ircd.rb +1 -1
- data/lib/rupircd/server.rb +499 -427
- data/rupircd.gemspec +2 -2
- metadata +2 -2
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.6.
|
1
|
+
0.6.3
|
data/ircd.rb
CHANGED
data/lib/rupircd/server.rb
CHANGED
@@ -22,6 +22,8 @@ require 'rupircd/charcode'
|
|
22
22
|
require 'rupircd/conf'
|
23
23
|
|
24
24
|
module IRCd
|
25
|
+
VERSION = "0.6.2"
|
26
|
+
|
25
27
|
class IRCServer < WEBrick::GenericServer
|
26
28
|
include Utils
|
27
29
|
include Reply
|
@@ -29,6 +31,19 @@ class IRCServer < WEBrick::GenericServer
|
|
29
31
|
|
30
32
|
include MonitorMixin
|
31
33
|
|
34
|
+
class <<self
|
35
|
+
def define_oper_command(mtd, &pr)
|
36
|
+
define_method(mtd){|usr, param|
|
37
|
+
if usr.operator || usr.local_operator
|
38
|
+
instance_eval(&pr)
|
39
|
+
else
|
40
|
+
send_server_message(usr, "481", "Permission Denied - You're not an IRC operator")
|
41
|
+
end
|
42
|
+
}
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
|
32
47
|
def initialize(fconf, *args)
|
33
48
|
@_init_args = [fconf, *args]
|
34
49
|
@fconf = fconf
|
@@ -144,6 +159,32 @@ class IRCServer < WEBrick::GenericServer
|
|
144
159
|
user.socket.close unless user.socket.closed?
|
145
160
|
end
|
146
161
|
|
162
|
+
def recv_message(user, line)
|
163
|
+
line.chomp!
|
164
|
+
return if line.empty?
|
165
|
+
begin
|
166
|
+
msg = Message.parse(line)
|
167
|
+
params = msg.params
|
168
|
+
@used[msg.command.upcase][0] += 1
|
169
|
+
mtd = "on_" + msg.command.downcase
|
170
|
+
if respond_to?(mtd)
|
171
|
+
__send__(mtd, user, params)
|
172
|
+
else
|
173
|
+
raise UnknownCommand.new(msg.command)
|
174
|
+
end
|
175
|
+
rescue NotEnoughParameter => e
|
176
|
+
send_server_message(user, "461", msg.command, "Not enough parameters")
|
177
|
+
rescue UnknownCommand => e
|
178
|
+
send_server_message(user, "421", e.cmd, "Unknown command")
|
179
|
+
rescue
|
180
|
+
puts $!, $@
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
def on_motd(user, params)
|
185
|
+
print_motd(user)
|
186
|
+
end
|
187
|
+
|
147
188
|
def print_motd(user)
|
148
189
|
send_server_message(user, "375", "- #{config[:ServerName]} Message of the day - ")
|
149
190
|
config[:Motd].each_line{|line|
|
@@ -153,463 +194,494 @@ class IRCServer < WEBrick::GenericServer
|
|
153
194
|
send_server_message(user, "376", "End of MOTD command")
|
154
195
|
end
|
155
196
|
|
156
|
-
def
|
157
|
-
|
158
|
-
|
197
|
+
def on_lusers(user, params)
|
198
|
+
send_server_message(user, "251", "There are #{@users.size} users and 0 services on 1 servers")
|
199
|
+
unless @operators.empty?
|
200
|
+
send_server_message(user, "252", @operators.size, "operator(s) online")
|
201
|
+
end
|
202
|
+
unless @channels.empty?
|
203
|
+
send_server_message(user, "254", @channels.size, "channels formed")
|
204
|
+
end
|
205
|
+
send_server_message(user, "255", "I have #{@users.size} clients and 0 servers")
|
206
|
+
end
|
207
|
+
|
208
|
+
def on_oper(user, params)
|
209
|
+
raise NotEnoughParameter if params.size < 2
|
210
|
+
nick, pass = params
|
211
|
+
unless opdic = config.fetch(:Opers,{}).find{|k, v| k =~ nick}
|
212
|
+
send_server_message(user, "491", "No O-lines for your host")
|
213
|
+
return
|
214
|
+
end
|
215
|
+
if Digest::MD5.hexdigest(pass) == opdic[1]
|
216
|
+
user.operator = true
|
217
|
+
user.local_operator = true
|
218
|
+
@operators.push user
|
219
|
+
send_server_message(user, "381", "You are now an IRC operator")
|
159
220
|
else
|
160
|
-
send_server_message(
|
221
|
+
send_server_message(user, "464", "Password incorrect")
|
161
222
|
end
|
162
223
|
end
|
163
224
|
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
send_server_message(user, "212", cmd, val[0])
|
238
|
-
}
|
239
|
-
when ?o
|
240
|
-
|
241
|
-
when ?u
|
242
|
-
vs = Time.now.to_i - @started.to_i
|
243
|
-
days = vs / (3600*24)
|
244
|
-
vs -= days * 3600 * 24
|
245
|
-
hours = vs / 3600
|
246
|
-
vs -= hours * 3600
|
247
|
-
minutes = vs/60
|
248
|
-
vs -= minutes * 60
|
249
|
-
send_server_message(user, "242", format("Server Up %d days %d:%02d:%02d",days,hours,minutes,vs))
|
250
|
-
end
|
251
|
-
send_server_message(user, "219", c.chr, "End of STATS report")
|
252
|
-
when JOIN
|
253
|
-
if params[0] == "0"
|
254
|
-
user.joined_channels.each{|ch|
|
255
|
-
channel(ch).part(user, "")
|
256
|
-
}
|
257
|
-
user.joined_channels = []
|
258
|
-
else
|
259
|
-
chs = params[0].split(",")
|
260
|
-
keys = msg.params[1].split(",") if params.size >= 2
|
261
|
-
keys ||= []
|
262
|
-
chs.each_with_index{|ch, i|
|
263
|
-
unless channame?(ch)
|
264
|
-
send_server_message(user, "403", ch, "No such channel")
|
265
|
-
next
|
266
|
-
end
|
267
|
-
|
268
|
-
chclass = case ch
|
269
|
-
when /^\+/
|
270
|
-
NoModeChannel
|
271
|
-
when /^#/
|
272
|
-
Channel
|
273
|
-
when /^!#/
|
274
|
-
SafeChannel
|
275
|
-
end
|
276
|
-
unless @channels.has_key?(ch.downcase)
|
277
|
-
set_channel(ch, chclass.new(self, user, ch) )
|
278
|
-
handle_reply(user, channel(ch).join(user, keys[i]))
|
279
|
-
else
|
280
|
-
rpl = channel(ch).join(user, keys[i])
|
281
|
-
handle_reply(user, rpl)
|
282
|
-
end
|
283
|
-
}
|
284
|
-
end
|
285
|
-
when PART
|
286
|
-
ch, msg = params
|
287
|
-
msg ||= ""
|
288
|
-
chs = ch.split(",")
|
289
|
-
chs.each{|chname|
|
290
|
-
ch = channel(chname)
|
291
|
-
ch.part(user, msg)
|
292
|
-
if ch.members.empty?
|
293
|
-
@channels.delete(chname.downcase)
|
294
|
-
end
|
295
|
-
user.joined_channels.delete(ch)
|
296
|
-
}
|
297
|
-
when PING
|
298
|
-
send_client_message(user, config[:ServerName], PONG, config[:ServerName], *params)
|
299
|
-
when INFO
|
300
|
-
config[:Info].each_line{|line|
|
301
|
-
line.chomp!
|
302
|
-
send_server_message(user, "371", line)
|
303
|
-
}
|
304
|
-
send_server_message(user, "374", "End of INFO list")
|
305
|
-
when LINKS
|
306
|
-
send_server_message(user, "365")
|
307
|
-
when TIME
|
308
|
-
send_server_message(user, "391", config[:ServerName], Time.now.to_s)
|
309
|
-
when PONG
|
310
|
-
@ping_threads[user].kill
|
311
|
-
start_ping(user)
|
312
|
-
when INVITE
|
313
|
-
if params.size < 2
|
314
|
-
raise NotEnoughParameter
|
315
|
-
else
|
316
|
-
who, to = params
|
317
|
-
if target = @users.find{|v| v.nick == who}
|
318
|
-
if target.away?
|
319
|
-
msg = target.away
|
320
|
-
send_server_message(user, "301", who, msg)
|
321
|
-
return
|
322
|
-
end
|
323
|
-
if ch = channel(to)
|
324
|
-
handle_reply(user, ch.invite(user, target))
|
325
|
-
else
|
326
|
-
send_server_message(user, "401", who, "No such nick/channel")
|
327
|
-
end
|
328
|
-
else
|
329
|
-
send_server_message(user, "401", who, "No such nick/channel")
|
330
|
-
end
|
331
|
-
end
|
332
|
-
when LIST
|
333
|
-
if params.empty?
|
334
|
-
chs = @channels.find_all{|k, v| v.visible?(nil)}
|
335
|
-
chs.each{|k, v|
|
336
|
-
case (tpc = v.get_topic(user, true))[0]
|
337
|
-
when "331"
|
338
|
-
tpc = ""
|
339
|
-
else
|
340
|
-
tpc = tpc[-1]
|
341
|
-
end
|
342
|
-
send_server_message(user, "322", k, v.members.size.to_s, tpc)
|
343
|
-
}
|
344
|
-
else
|
345
|
-
chs = params[0].split(",").find_all{|name| channel(name) && channel(n).visible?(user)}
|
346
|
-
chs.each{|k|
|
347
|
-
v = channel(k)
|
348
|
-
uss = v.members.find_all{|m| !m.invisible}
|
349
|
-
case (tpc = v.get_topic(user, true))[0]
|
350
|
-
when "331"
|
351
|
-
tpc = ""
|
352
|
-
else
|
353
|
-
tpc = tpc[-1]
|
354
|
-
end
|
355
|
-
send_server_message(user, "322", k, v.members.size.to_s, tpc)
|
356
|
-
}
|
357
|
-
end
|
358
|
-
send_server_message(user, "323", "End of LIST")
|
359
|
-
when TOPIC
|
360
|
-
chn, topic = params
|
361
|
-
unless ch = channel(chn)
|
362
|
-
send_server_message(user, "403", chn, "No such channel")
|
363
|
-
return
|
364
|
-
end
|
365
|
-
if params.size < 1
|
366
|
-
raise NotEnoughParameter
|
367
|
-
elsif params.size == 1
|
368
|
-
send_server_message(user, *ch.get_topic(user))
|
369
|
-
else
|
370
|
-
handle_reply(user, ch.set_topic(user, topic))
|
371
|
-
end
|
372
|
-
when PRIVMSG
|
373
|
-
if params.size < 2
|
374
|
-
raise NotEnoughParameter
|
225
|
+
define_oper_command :on_close do |user, params|
|
226
|
+
@users.synchronize do
|
227
|
+
@users.each{|s| unregister(s) }
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
define_oper_command :on_die do |usr, params|
|
232
|
+
shutdown
|
233
|
+
exit!
|
234
|
+
end
|
235
|
+
|
236
|
+
define_oper_command :on_rehash do |usr, params|
|
237
|
+
cnf = @fconf.load
|
238
|
+
|
239
|
+
if Hash === cnf
|
240
|
+
config.replace(cnf)
|
241
|
+
send_server_message(usr, "382", "#{@fconf.path} :Rehashing")
|
242
|
+
else
|
243
|
+
raise "Invalid Conf file"
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
define_oper_command :on_restart do |usr, params|
|
248
|
+
@users.each{|s| unregister(s) }
|
249
|
+
init
|
250
|
+
end
|
251
|
+
|
252
|
+
def on_version(user, params)
|
253
|
+
send_server_message(user, "351", "rupircd-#{VERSION} #{config[:ServerName]} :Ruby Pseudo IRCD 0.1b")
|
254
|
+
end
|
255
|
+
|
256
|
+
def on_stats(user, params)
|
257
|
+
if params.empty?
|
258
|
+
raise NotEnoughParameter
|
259
|
+
return
|
260
|
+
end
|
261
|
+
c = params[0][0]
|
262
|
+
case c
|
263
|
+
when ?l
|
264
|
+
|
265
|
+
when ?m
|
266
|
+
@used.each_pair{|cmd, val|
|
267
|
+
send_server_message(user, "212", cmd, val[0])
|
268
|
+
}
|
269
|
+
when ?o
|
270
|
+
|
271
|
+
when ?u
|
272
|
+
vs = Time.now.to_i - @started.to_i
|
273
|
+
days = vs / (3600*24)
|
274
|
+
vs -= days * 3600 * 24
|
275
|
+
hours = vs / 3600
|
276
|
+
vs -= hours * 3600
|
277
|
+
minutes = vs/60
|
278
|
+
vs -= minutes * 60
|
279
|
+
send_server_message(user, "242", format("Server Up %d days %d:%02d:%02d",days,hours,minutes,vs))
|
280
|
+
end
|
281
|
+
send_server_message(user, "219", c.chr, "End of STATS report")
|
282
|
+
end
|
283
|
+
|
284
|
+
def on_join(user, params)
|
285
|
+
if params[0] == "0"
|
286
|
+
user.joined_channels.each{|ch|
|
287
|
+
channel(ch).part(user, "")
|
288
|
+
}
|
289
|
+
user.joined_channels = []
|
290
|
+
else
|
291
|
+
chs = params[0].split(",")
|
292
|
+
keys = params[1].split(",") if params.size >= 2
|
293
|
+
keys ||= []
|
294
|
+
chs.each_with_index{|ch, i|
|
295
|
+
unless channame?(ch)
|
296
|
+
send_server_message(user, "403", ch, "No such channel")
|
297
|
+
next
|
375
298
|
end
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
if who.away?
|
385
|
-
away = who.away
|
386
|
-
send_server_message(user, "301", to, away)
|
387
|
-
else
|
388
|
-
send_client_message(who, user, PRIVMSG, who.nick, msg)
|
389
|
-
end
|
390
|
-
else
|
391
|
-
send_server_message(user, "401", to, "No such nick/channel")
|
299
|
+
|
300
|
+
chclass = case ch
|
301
|
+
when /^\+/
|
302
|
+
NoModeChannel
|
303
|
+
when /^#/
|
304
|
+
Channel
|
305
|
+
when /^!#/
|
306
|
+
SafeChannel
|
392
307
|
end
|
393
|
-
|
394
|
-
|
395
|
-
|
308
|
+
unless @channels.has_key?(ch.downcase)
|
309
|
+
set_channel(ch, chclass.new(self, user, ch) )
|
310
|
+
handle_reply(user, channel(ch).join(user, keys[i]))
|
396
311
|
else
|
397
|
-
|
398
|
-
|
399
|
-
handle_reply(user, channel(ch).names(user))
|
400
|
-
}
|
312
|
+
rpl = channel(ch).join(user, keys[i])
|
313
|
+
handle_reply(user, rpl)
|
401
314
|
end
|
402
|
-
|
403
|
-
|
404
|
-
|
315
|
+
}
|
316
|
+
end
|
317
|
+
end
|
318
|
+
|
319
|
+
def on_part(user, params)
|
320
|
+
ch, msg = params
|
321
|
+
msg ||= ""
|
322
|
+
chs = ch.split(",")
|
323
|
+
chs.each{|chname|
|
324
|
+
ch = channel(chname)
|
325
|
+
ch.part(user, msg)
|
326
|
+
if ch.members.empty?
|
327
|
+
@channels.delete(chname.downcase)
|
328
|
+
end
|
329
|
+
user.joined_channels.delete(ch)
|
330
|
+
}
|
331
|
+
end
|
332
|
+
|
333
|
+
def on_ping(user, params)
|
334
|
+
send_client_message(user, config[:ServerName], PONG, config[:ServerName], *params)
|
335
|
+
end
|
336
|
+
|
337
|
+
def on_info(user, params)
|
338
|
+
config[:Info].each_line{|line|
|
339
|
+
line.chomp!
|
340
|
+
send_server_message(user, "371", line)
|
341
|
+
}
|
342
|
+
send_server_message(user, "374", "End of INFO list")
|
343
|
+
end
|
344
|
+
|
345
|
+
def on_links(user, params)
|
346
|
+
send_server_message(user, "365")
|
347
|
+
end
|
348
|
+
|
349
|
+
def on_time(user, params)
|
350
|
+
send_server_message(user, "391", config[:ServerName], Time.now.to_s)
|
351
|
+
end
|
352
|
+
|
353
|
+
def on_pong(user, params)
|
354
|
+
@ping_threads[user].kill
|
355
|
+
start_ping(user)
|
356
|
+
end
|
357
|
+
|
358
|
+
def on_invite(user, params)
|
359
|
+
if params.size < 2
|
360
|
+
raise NotEnoughParameter
|
361
|
+
else
|
362
|
+
who, to = params
|
363
|
+
if target = @users.find{|v| v.nick == who}
|
364
|
+
if target.away?
|
365
|
+
msg = target.away
|
366
|
+
send_server_message(user, "301", who, msg)
|
405
367
|
return
|
406
368
|
end
|
407
|
-
to, msg = params
|
408
369
|
if ch = channel(to)
|
409
|
-
|
410
|
-
send_server_message(user, "412", "No text to send")
|
411
|
-
else
|
412
|
-
handle_reply(user, ch.notice(user, msg))
|
413
|
-
end
|
414
|
-
elsif who = @users.find{|v| v.nick == to}
|
415
|
-
send_client_message(who, user, NOTICE, user.nick, msg)
|
370
|
+
handle_reply(user, ch.invite(user, target))
|
416
371
|
else
|
417
|
-
send_server_message(user, "401",
|
372
|
+
send_server_message(user, "401", who, "No such nick/channel")
|
418
373
|
end
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
374
|
+
else
|
375
|
+
send_server_message(user, "401", who, "No such nick/channel")
|
376
|
+
end
|
377
|
+
end
|
378
|
+
end
|
379
|
+
|
380
|
+
def on_list(user, params)
|
381
|
+
if params.empty?
|
382
|
+
chs = @channels.find_all{|k, v| v.visible?(nil)}
|
383
|
+
chs.each{|k, v|
|
384
|
+
case (tpc = v.get_topic(user, true))[0]
|
385
|
+
when "331"
|
386
|
+
tpc = ""
|
423
387
|
else
|
424
|
-
|
425
|
-
send_server_message(user, "306", "You have been marked as being away")
|
426
|
-
end
|
427
|
-
when MODE
|
428
|
-
if params.size < 1
|
429
|
-
raise NotEnoughParameter
|
430
|
-
return
|
388
|
+
tpc = tpc[-1]
|
431
389
|
end
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
end
|
443
|
-
else
|
444
|
-
send_server_message(user, "502", "Cannot change mode for other users")
|
445
|
-
end
|
390
|
+
send_server_message(user, "322", k, v.members.size.to_s, tpc)
|
391
|
+
}
|
392
|
+
else
|
393
|
+
chs = params[0].split(",").find_all{|name| channel(name) && channel(n).visible?(user)}
|
394
|
+
chs.each{|k|
|
395
|
+
v = channel(k)
|
396
|
+
uss = v.members.find_all{|m| !m.invisible}
|
397
|
+
case (tpc = v.get_topic(user, true))[0]
|
398
|
+
when "331"
|
399
|
+
tpc = ""
|
446
400
|
else
|
447
|
-
|
401
|
+
tpc = tpc[-1]
|
448
402
|
end
|
449
|
-
|
403
|
+
send_server_message(user, "322", k, v.members.size.to_s, tpc)
|
404
|
+
}
|
405
|
+
end
|
406
|
+
send_server_message(user, "323", "End of LIST")
|
407
|
+
end
|
408
|
+
|
409
|
+
def on_topic(user, params)
|
410
|
+
chn, topic = params
|
411
|
+
unless ch = channel(chn)
|
412
|
+
send_server_message(user, "403", chn, "No such channel")
|
413
|
+
return
|
414
|
+
end
|
415
|
+
if params.size < 1
|
416
|
+
raise NotEnoughParameter
|
417
|
+
elsif params.size == 1
|
418
|
+
send_server_message(user, *ch.get_topic(user))
|
419
|
+
else
|
420
|
+
handle_reply(user, ch.set_topic(user, topic))
|
421
|
+
end
|
422
|
+
end
|
423
|
+
|
424
|
+
def on_privmsg(user, params)
|
425
|
+
if params.size < 2
|
426
|
+
raise NotEnoughParameter
|
427
|
+
end
|
428
|
+
to, msg = params
|
429
|
+
if ch = channel(to)
|
430
|
+
if msg.empty?
|
431
|
+
send_server_message(user, "412", "No text to send")
|
432
|
+
else
|
433
|
+
handle_reply(user, ch.privmsg(user, msg))
|
434
|
+
end
|
435
|
+
elsif who = @users.find{|v| v.nick == to}
|
436
|
+
if who.away?
|
437
|
+
away = who.away
|
438
|
+
send_server_message(user, "301", to, away)
|
439
|
+
else
|
440
|
+
send_client_message(who, user, PRIVMSG, who.nick, msg)
|
441
|
+
end
|
442
|
+
else
|
443
|
+
send_server_message(user, "401", to, "No such nick/channel")
|
444
|
+
end
|
445
|
+
end
|
446
|
+
|
447
|
+
def on_names(user, params)
|
448
|
+
if params.size < 1
|
449
|
+
raise NotEnoughParameter
|
450
|
+
else
|
451
|
+
chs = params[0].split(",")
|
452
|
+
chs.each{|ch|
|
453
|
+
handle_reply(user, channel(ch).names(user))
|
454
|
+
}
|
455
|
+
end
|
456
|
+
end
|
457
|
+
|
458
|
+
def on_notice(user, params)
|
459
|
+
if params.size < 2
|
460
|
+
raise NotEnoughParameter
|
461
|
+
return
|
462
|
+
end
|
463
|
+
to, msg = params
|
464
|
+
if ch = channel(to)
|
465
|
+
if msg.empty?
|
466
|
+
send_server_message(user, "412", "No text to send")
|
467
|
+
else
|
468
|
+
handle_reply(user, ch.notice(user, msg))
|
469
|
+
end
|
470
|
+
elsif who = @users.find{|v| v.nick == to}
|
471
|
+
send_client_message(who, user, NOTICE, user.nick, msg)
|
472
|
+
else
|
473
|
+
send_server_message(user, "401", to, "No such nick/channel")
|
474
|
+
end
|
475
|
+
end
|
476
|
+
|
477
|
+
def on_away(user, params)
|
478
|
+
if params.empty? || params[0].empty?
|
479
|
+
user.away = ""
|
480
|
+
send_server_message(user, "305", "You are no longer marked as being away")
|
481
|
+
else
|
482
|
+
user.away = params.shift
|
483
|
+
send_server_message(user, "306", "You have been marked as being away")
|
484
|
+
end
|
485
|
+
end
|
486
|
+
|
487
|
+
def on_mode(user, params)
|
488
|
+
if params.size < 1
|
489
|
+
raise NotEnoughParameter
|
490
|
+
return
|
491
|
+
end
|
492
|
+
to = params.shift
|
493
|
+
if ch = channel(to)
|
494
|
+
handle_reply(user, ch.handle_mode(user, params))
|
495
|
+
elsif who = @users.find{|v| v.nick == to}
|
496
|
+
if who == user
|
450
497
|
if params.empty?
|
451
|
-
send_server_message(user, "
|
498
|
+
send_server_message(user, "221", who.get_mode_flags)
|
452
499
|
else
|
453
|
-
|
454
|
-
|
455
|
-
nick = user.identifier.to_s
|
456
|
-
elsif !correct_nick?(nick)
|
457
|
-
send_server_message(user, "432", nick, "Erroneous nickname")
|
458
|
-
return
|
459
|
-
end
|
460
|
-
if us = user_from_nick(nick)
|
461
|
-
return if us == user
|
462
|
-
send_server_message(user, "433", nick, "Nickname is already in use")
|
463
|
-
elsif user.restriction
|
464
|
-
send_server_message(user, "484", "Your connection is restricted!")
|
465
|
-
else
|
466
|
-
send_client_message(user, user, NICK, nick)
|
467
|
-
sent = []
|
468
|
-
user.joined_channels.each{|ch|
|
469
|
-
ch.members.each{|mem|
|
470
|
-
if !sent.include?(mem) && mem != user
|
471
|
-
sent << mem
|
472
|
-
send_client_message(mem, user, NICK, nick)
|
473
|
-
end
|
474
|
-
}
|
475
|
-
}
|
476
|
-
@old_nicks[nick].unshift user.to_a
|
477
|
-
user.nick = nick
|
478
|
-
end
|
500
|
+
rls = who.set_flags(params[0])
|
501
|
+
send_client_message(user, user, MODE, user.nick, rls.join(" "))
|
479
502
|
end
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
503
|
+
else
|
504
|
+
send_server_message(user, "502", "Cannot change mode for other users")
|
505
|
+
end
|
506
|
+
else
|
507
|
+
send_server_message(user, "401", to, "No such nick/channel")
|
508
|
+
end
|
509
|
+
end
|
510
|
+
|
511
|
+
def on_nick(user, params)
|
512
|
+
if params.empty?
|
513
|
+
send_server_message(user, "431", "No nickname given")
|
514
|
+
else
|
515
|
+
nick = params[0]
|
516
|
+
if nick == "0"
|
517
|
+
nick = user.identifier.to_s
|
518
|
+
elsif !correct_nick?(nick)
|
519
|
+
send_server_message(user, "432", nick, "Erroneous nickname")
|
520
|
+
return
|
521
|
+
end
|
522
|
+
if us = user_from_nick(nick)
|
523
|
+
return if us == user
|
524
|
+
send_server_message(user, "433", nick, "Nickname is already in use")
|
525
|
+
elsif user.restriction
|
526
|
+
send_server_message(user, "484", "Your connection is restricted!")
|
527
|
+
else
|
528
|
+
send_client_message(user, user, NICK, nick)
|
529
|
+
sent = []
|
530
|
+
user.joined_channels.each{|ch|
|
531
|
+
ch.members.each{|mem|
|
532
|
+
if !sent.include?(mem) && mem != user
|
533
|
+
sent << mem
|
534
|
+
send_client_message(mem, user, NICK, nick)
|
535
|
+
end
|
536
|
+
}
|
537
|
+
}
|
538
|
+
@old_nicks[nick].unshift user.to_a
|
539
|
+
user.nick = nick
|
540
|
+
end
|
541
|
+
end
|
542
|
+
end
|
543
|
+
|
544
|
+
def on_user(user, params)
|
545
|
+
puts_socket(user, ERR_ALREADYREGISTRED.new(config[:ServerName], "462", [user.nick, "Unauthorized command (already registered)"]))
|
546
|
+
end
|
547
|
+
|
548
|
+
def on_pass(user, params)
|
549
|
+
puts_socket(user, ERR_ALREADYREGISTRED.new(config[:ServerName], "462", [user.nick, "Unauthorized command (already registered)"]))
|
550
|
+
end
|
551
|
+
|
552
|
+
def on_whois(user, params)
|
553
|
+
raise NotEnoughParameter if params.empty?
|
554
|
+
params[0].split(",").each{|mask|
|
555
|
+
reg = mask_to_regex(mask)
|
556
|
+
matched = @users.find_all{|usr| usr.nick =~ reg}
|
557
|
+
if matched.empty?
|
558
|
+
send_server_message(user, "401", mask, "No such nick/channel")
|
559
|
+
else
|
560
|
+
matched.each{|target|
|
561
|
+
sc = target.socket
|
562
|
+
send_server_message(user, "311", target.nick, target.user, target.host, "*", target.real)
|
563
|
+
send_server_message(user, "312", target.nick, config[:ServerName], "this server.")
|
564
|
+
send_server_message(user, "313", target.nick, "is an IRC operator") if @operators.include?(target)
|
565
|
+
chs = []
|
566
|
+
target.joined_channels.each{|ch|
|
567
|
+
if ch.visible?(user)
|
568
|
+
pr = ""
|
569
|
+
if ch.mode.op?(target)
|
570
|
+
pr = "@"
|
571
|
+
else ch.mode.voiced?(target)
|
572
|
+
pr = "+"
|
511
573
|
end
|
512
|
-
|
513
|
-
|
574
|
+
chs << pr+ch.name
|
575
|
+
end
|
576
|
+
}
|
577
|
+
send_server_message(user, "319", target.nick, chs.join(" "))
|
578
|
+
if target.away?
|
579
|
+
away = target.away
|
580
|
+
send_server_message(user, "301", target.nick, away)
|
514
581
|
end
|
582
|
+
send_server_message(user, "318", target.nick, "End of WHOIS list")
|
583
|
+
}
|
584
|
+
end
|
585
|
+
}
|
586
|
+
end
|
587
|
+
|
588
|
+
def on_whowas(user, params)
|
589
|
+
raise NotEnoughParameter if params.empty?
|
590
|
+
params[0].split(",").each{|nick|
|
591
|
+
if @users.any?{|us| us.nick == nick}
|
592
|
+
send_server_message(user, "312", nick, config[:ServerName], "this server.")
|
593
|
+
elsif @old_nicks[nick].empty?
|
594
|
+
send_server_message(user, "406", nick, "There was no such nickname")
|
595
|
+
else
|
596
|
+
@old_nicks[nick].each{|nms|
|
597
|
+
send_server_message(user, "314", *nms)
|
515
598
|
}
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
599
|
+
end
|
600
|
+
send_server_message(user, "369", nick, "End of WHOWAS")
|
601
|
+
}
|
602
|
+
end
|
603
|
+
|
604
|
+
def on_who(user, params)
|
605
|
+
raise NotEnoughParameter if params.empty?
|
606
|
+
mask = mask_to_regex(params[0])
|
607
|
+
chs = @channels.find_all{|name, ch| name =~ mask && ch.visible?(user)}
|
608
|
+
unless chs.empty?
|
609
|
+
chs.each{|name, ch|
|
610
|
+
ch.members.each{|usr|
|
611
|
+
sym = usr.away? ? "G" : "H"
|
612
|
+
sym += @operators.include?(usr) ? "*" : ""
|
613
|
+
sym += ch.mode.op?(usr) ? "@" : (ch.mode.voiced?(usr) ? "+" : "")
|
614
|
+
send_server_message(user, "352", usr.name, usr.user, usr.host, config[:ServerName], usr.nick, sym, "0 #{real}")
|
615
|
+
}
|
616
|
+
send_server_message(user, "315", name, "End of WHO list")
|
617
|
+
}
|
618
|
+
else
|
619
|
+
usrs = @users.find_all{|us| us.nick =~ mask || us.user =~ mask || us.host =~ mask}
|
620
|
+
usrs.each{|usr|
|
621
|
+
send_server_message(user, "352", "*", usr.user, usr.host, config[:ServerName], usr.nick, "H", "0 #{usr.real}")
|
622
|
+
send_server_message(user, "315", usr.nick, "End of WHO list")
|
623
|
+
}
|
624
|
+
end
|
625
|
+
end
|
626
|
+
|
627
|
+
def on_kick(user, params)
|
628
|
+
raise NotEnoughParameter if params.size < 2
|
629
|
+
chs = params[0].split(",")
|
630
|
+
whos = params[1].split(",")
|
631
|
+
msg = params[2].to_s
|
632
|
+
if chs.size == 1
|
633
|
+
if ch = channel(chs[0])
|
634
|
+
whos.each{|who|
|
635
|
+
if usr = @users.find{|us|us.nick==who}
|
636
|
+
handle_reply user, ch.kick(usr, user, msg)
|
523
637
|
else
|
524
|
-
|
525
|
-
send_server_message(user, "314", *nms)
|
526
|
-
}
|
638
|
+
send_server_message(user, "401", who, "No such nick/channel")
|
527
639
|
end
|
528
|
-
send_server_message(user, "369", nick, "End of WHOWAS")
|
529
640
|
}
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
sym += @operators.include?(usr) ? "*" : ""
|
539
|
-
sym += ch.mode.op?(usr) ? "@" : (ch.mode.voiced?(usr) ? "+" : "")
|
540
|
-
send_server_message(user, "352", usr.name, usr.user, usr.host, config[:ServerName], usr.nick, sym, "0 #{real}")
|
541
|
-
}
|
542
|
-
send_server_message(user, "315", name, "End of WHO list")
|
543
|
-
}
|
544
|
-
else
|
545
|
-
usrs = @users.find_all{|us| us.nick =~ mask || us.user =~ mask || us.host =~ mask}
|
546
|
-
usrs.each{|usr|
|
547
|
-
send_server_message(user, "352", "*", usr.user, usr.host, config[:ServerName], usr.nick, "H", "0 #{usr.real}")
|
548
|
-
send_server_message(user, "315", usr.nick, "End of WHO list")
|
549
|
-
}
|
550
|
-
end
|
551
|
-
when KICK
|
552
|
-
raise NotEnoughParameter if params.size < 2
|
553
|
-
chs = params[0].split(",")
|
554
|
-
whos = params[1].split(",")
|
555
|
-
msg = params[2].to_s
|
556
|
-
if chs.size == 1
|
557
|
-
if ch = channel(chs[0])
|
558
|
-
whos.each{|who|
|
559
|
-
if usr = @users.find{|us|us.nick==who}
|
560
|
-
handle_reply user, ch.kick(usr, user, msg)
|
561
|
-
else
|
562
|
-
send_server_message(user, "401", who, "No such nick/channel")
|
563
|
-
end
|
564
|
-
}
|
641
|
+
else
|
642
|
+
send_server_message(user, "403", chs[0], "No such channel")
|
643
|
+
end
|
644
|
+
elsif chs.size == whos.size
|
645
|
+
chs.each_with_index{|chn, i|
|
646
|
+
if chn = channel(chn)
|
647
|
+
if usr = user_from_nick[whos[i]]
|
648
|
+
handle_reply user, ch.kick(usr, user, msg)
|
565
649
|
else
|
566
|
-
send_server_message(user, "
|
650
|
+
send_server_message(user, "401", whos[i], "No such nick/channel")
|
567
651
|
end
|
568
|
-
|
569
|
-
|
570
|
-
if chn = channel(chn)
|
571
|
-
if usr = user_from_nick[whos[i]]
|
572
|
-
handle_reply user, ch.kick(usr, user, msg)
|
573
|
-
else
|
574
|
-
send_server_message(user, "401", whos[i], "No such nick/channel")
|
575
|
-
end
|
576
|
-
else
|
577
|
-
send_server_message(user, "403", chn, "No such channel")
|
578
|
-
end
|
579
|
-
}
|
652
|
+
else
|
653
|
+
send_server_message(user, "403", chn, "No such channel")
|
580
654
|
end
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
|
587
|
-
|
588
|
-
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
send_client_message(user, nil, ERROR, "Closing", "Link:", "#{user.nick}[#{user.user}@#{user.host}]", %Q!("#{params[0]}")!)
|
602
|
-
unregister(user, params[0])
|
655
|
+
}
|
656
|
+
end
|
657
|
+
end
|
658
|
+
|
659
|
+
def on_ison(user, params)
|
660
|
+
raise NotEnoughParameter if params.empty?
|
661
|
+
a = params.find_all{|nick| @users.any?{|us| us.nick == nick}}
|
662
|
+
send_server_message(user, "303", a.join(" "))
|
663
|
+
end
|
664
|
+
|
665
|
+
def on_userhost(user, params)
|
666
|
+
raise NotEnoughParameter if params.empty?
|
667
|
+
targs = params[0..4]
|
668
|
+
targs.map!{|nick|
|
669
|
+
if tg = @users.find{|u| u.nick == nick}
|
670
|
+
suf = @operators.include?(tg.socket) ? "*" : ""
|
671
|
+
pre = tg.away? ? "-" : "+"
|
672
|
+
usr = tg.user
|
673
|
+
host = tg.host
|
674
|
+
nick + suf + "=" + pre + usr + "@" + host + " "
|
603
675
|
else
|
604
|
-
|
676
|
+
""
|
605
677
|
end
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
|
678
|
+
}
|
679
|
+
send_server_message(user, "302", targs.join(" "))
|
680
|
+
end
|
681
|
+
|
682
|
+
def on_quit(user, params)
|
683
|
+
send_client_message(user, nil, ERROR, "Closing", "Link:", "#{user.nick}[#{user.user}@#{user.host}]", %Q!("#{params[0]}")!)
|
684
|
+
unregister(user, params[0])
|
613
685
|
end
|
614
686
|
|
615
687
|
def handle_reply(user, rpl)
|
@@ -674,4 +746,4 @@ class IRCServer < WEBrick::GenericServer
|
|
674
746
|
end
|
675
747
|
|
676
748
|
end
|
677
|
-
end
|
749
|
+
end
|
data/rupircd.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{rupircd}
|
8
|
-
s.version = "0.6.
|
8
|
+
s.version = "0.6.3"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["konn"]
|
12
|
-
s.date = %q{2009-08-
|
12
|
+
s.date = %q{2009-08-13}
|
13
13
|
s.description = %q{rupircd is a light IRC daemon written in 100% pure ruby.}
|
14
14
|
s.email = %q{mr_konn[at]jcom[dot]home[dot]ne[dot]jp}
|
15
15
|
s.executables = ["mkpassword", "rupircd"]
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: konn-rupircd
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.6.
|
4
|
+
version: 0.6.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- konn
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-08-
|
12
|
+
date: 2009-08-13 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|