summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGiuseppe Bilotta <giuseppe.bilotta@gmail.com>2008-06-23 00:40:38 +0200
committerGiuseppe Bilotta <giuseppe.bilotta@gmail.com>2008-06-23 01:11:36 +0200
commit3dd9db1a0e819a0b325476bdde24cbebd29bf548 (patch)
tree1e6e10062bbef4f57493a3546073c3281c3c8580
parentc2aa896a7c3f7623455b83214dde4379f940bbe5 (diff)
rfc2812.rb: refactor MODE parsing to use it for RPL_CHANNELMODEIS (324) too
-rw-r--r--lib/rbot/rfc2812.rb210
1 files changed, 108 insertions, 102 deletions
diff --git a/lib/rbot/rfc2812.rb b/lib/rbot/rfc2812.rb
index f4487bdb..647b986c 100644
--- a/lib/rbot/rfc2812.rb
+++ b/lib/rbot/rfc2812.rb
@@ -1285,6 +1285,9 @@ module Irc
handle(:who, data)
when RPL_ENDOFWHO
handle(:eowho, data)
+ when RPL_CHANNELMODEIS
+ parse_mode(serverstring, argv[1..-1], data)
+ handle(:mode, data)
else
handle(:unknown, data)
end
@@ -1401,108 +1404,7 @@ module Irc
handle(:nick, data)
when :MODE
- # MODE ([+-]<modes> (<params>)*)*
- # When a MODE message is received by a server,
- # Type C will have parameters too, so we must
- # be able to consume parameters for all
- # but Type D modes
-
- data[:target] = @server.user_or_channel(argv[0])
- data[:modestring] = argv[1..-1].join(" ")
- # data[:modes] is an array where each element
- # is an array with two elements, the first of which
- # is either :set or :reset, and the second symbol
- # is the mode letter. An optional third element
- # is present e.g. for channel modes that need
- # a parameter
- data[:modes] = []
- case data[:target]
- when User
- # User modes aren't currently handled internally,
- # but we still parse them and delegate to the client
- warning "Unhandled user mode message '#{serverstring}'"
- argv[1..-1].each { |arg|
- setting = arg[0].chr
- if "+-".include?(setting)
- setting = setting == "+" ? :set : :reset
- arg[1..-1].each_byte { |b|
- m = b.chr.intern
- data[:modes] << [setting, m]
- }
- else
- # Although typically User modes don't take an argument,
- # this is not true for all modes on all servers. Since
- # we have no knowledge of which modes take parameters
- # and which don't we just assign it to the last
- # mode. This is not going to do strange things often,
- # as usually User modes are only set one at a time
- warning "Unhandled user mode parameter #{arg} found"
- data[:modes].last << arg
- end
- }
- else
- # array of indices in data[:modes] where parameters
- # are needed
- who_wants_params = []
-
- modes = argv[1..-1].dup
- debug modes
- getting_args = false
- while arg = modes.shift
- debug arg
- if getting_args
- # getting args for previously set modes
- idx = who_wants_params.shift
- if idx.nil?
- warning "Oops, problems parsing #{serverstring.inspect}"
- break
- end
- data[:modes][idx] << arg
- getting_args = false if who_wants_params.empty?
- else
- debug @server.supports[:chanmodes]
- setting = :set
- arg.each_byte do |c|
- m = c.chr.intern
- case m
- when :+
- setting = :set
- when :-
- setting = :reset
- else
- data[:modes] << [setting, m]
- case m
- when *@server.supports[:chanmodes][:typea]
- who_wants_params << data[:modes].length - 1
- when *@server.supports[:chanmodes][:typeb]
- who_wants_params << data[:modes].length - 1
- when *@server.supports[:chanmodes][:typec]
- if setting == :set
- who_wants_params << data[:modes].length - 1
- end
- when *@server.supports[:chanmodes][:typed]
- # Nothing to do
- when *@server.supports[:prefix][:modes]
- who_wants_params << data[:modes].length - 1
- else
- warning "Unknown mode #{m} in #{serverstring.inspect}"
- end
- end
- end
- getting_args = true unless who_wants_params.empty?
- end
- end
-
- data[:modes].each { |mode|
- set, key, val = mode
- if val
- data[:target].mode[key].send(set, val)
- else
- data[:target].mode[key].send(set)
- end
- }
- end
-
+ parse_mode(serverstring, argv, data)
handle(:mode, data)
else
warning "Unknown message #{serverstring.inspect}"
@@ -1520,5 +1422,109 @@ module Irc
@handlers[key].call(data)
end
end
+
+ # RPL_CHANNELMODEIS
+ # MODE ([+-]<modes> (<params>)*)*
+ # When a MODE message is received by a server,
+ # Type C will have parameters too, so we must
+ # be able to consume parameters for all
+ # but Type D modes
+ def parse_mode(serverstring, argv, data)
+ data[:target] = @server.user_or_channel(argv[0])
+ data[:modestring] = argv[1..-1].join(" ")
+ # data[:modes] is an array where each element
+ # is an array with two elements, the first of which
+ # is either :set or :reset, and the second symbol
+ # is the mode letter. An optional third element
+ # is present e.g. for channel modes that need
+ # a parameter
+ data[:modes] = []
+ case data[:target]
+ when User
+ # User modes aren't currently handled internally,
+ # but we still parse them and delegate to the client
+ warning "Unhandled user mode message '#{serverstring}'"
+ argv[1..-1].each { |arg|
+ setting = arg[0].chr
+ if "+-".include?(setting)
+ setting = setting == "+" ? :set : :reset
+ arg[1..-1].each_byte { |b|
+ m = b.chr.intern
+ data[:modes] << [setting, m]
+ }
+ else
+ # Although typically User modes don't take an argument,
+ # this is not true for all modes on all servers. Since
+ # we have no knowledge of which modes take parameters
+ # and which don't we just assign it to the last
+ # mode. This is not going to do strange things often,
+ # as usually User modes are only set one at a time
+ warning "Unhandled user mode parameter #{arg} found"
+ data[:modes].last << arg
+ end
+ }
+ else
+ # array of indices in data[:modes] where parameters
+ # are needed
+ who_wants_params = []
+
+ modes = argv[1..-1].dup
+ debug modes
+ getting_args = false
+ while arg = modes.shift
+ debug arg
+ if getting_args
+ # getting args for previously set modes
+ idx = who_wants_params.shift
+ if idx.nil?
+ warning "Oops, problems parsing #{serverstring.inspect}"
+ break
+ end
+ data[:modes][idx] << arg
+ getting_args = false if who_wants_params.empty?
+ else
+ debug @server.supports[:chanmodes]
+ setting = :set
+ arg.each_byte do |c|
+ m = c.chr.intern
+ case m
+ when :+
+ setting = :set
+ when :-
+ setting = :reset
+ else
+ data[:modes] << [setting, m]
+ case m
+ when *@server.supports[:chanmodes][:typea]
+ who_wants_params << data[:modes].length - 1
+ when *@server.supports[:chanmodes][:typeb]
+ who_wants_params << data[:modes].length - 1
+ when *@server.supports[:chanmodes][:typec]
+ if setting == :set
+ who_wants_params << data[:modes].length - 1
+ end
+ when *@server.supports[:chanmodes][:typed]
+ # Nothing to do
+ when *@server.supports[:prefix][:modes]
+ who_wants_params << data[:modes].length - 1
+ else
+ warning "Unknown mode #{m} in #{serverstring.inspect}"
+ end
+ end
+ end
+ getting_args = true unless who_wants_params.empty?
+ end
+ end
+
+ data[:modes].each { |mode|
+ set, key, val = mode
+ if val
+ data[:target].mode[key].send(set, val)
+ else
+ data[:target].mode[key].send(set)
+ end
+ }
+ end
+ end
end
end