+#-- vim:sw=2:et
+#++
+#
+# :title: IRC Socket
+#
+# This module implements the IRC socket interface, including IRC message
+# penalty computation and the message queue system
+
+require 'monitor'
+
+class ::String
+ # Calculate the penalty which will be assigned to this message
+ # by the IRCd
+ def irc_send_penalty
+ # According to eggdrop, the initial penalty is
+ penalty = 1 + self.size/100
+ # on everything but UnderNET where it's
+ # penalty = 2 + self.size/120
+
+ cmd, pars = self.split($;,2)
+ debug "cmd: #{cmd}, pars: #{pars.inspect}"
+ case cmd.to_sym
+ when :KICK
+ chan, nick, msg = pars.split
+ chan = chan.split(',')
+ nick = nick.split(',')
+ penalty += nick.size
+ penalty *= chan.size
+ when :MODE
+ chan, modes, argument = pars.split
+ extra = 0
+ if modes
+ extra = 1
+ if argument
+ extra += modes.split(/\+|-/).size
+ else
+ extra += 3 * modes.split(/\+|-/).size
+ end
+ end
+ if argument
+ extra += 2 * argument.split.size
+ end
+ penalty += extra * chan.split.size
+ when :TOPIC
+ penalty += 1
+ penalty += 2 unless pars.split.size < 2
+ when :PRIVMSG, :NOTICE
+ dests = pars.split($;,2).first
+ penalty += dests.split(',').size
+ when :WHO
+ args = pars.split
+ if args.length > 0
+ penalty += args.inject(0){ |sum,x| sum += ((x.length > 4) ? 3 : 5) }
+ else
+ penalty += 10
+ end
+ when :PART
+ penalty += 4
+ when :AWAY, :JOIN, :VERSION, :TIME, :TRACE, :WHOIS, :DNS
+ penalty += 2
+ when :INVITE, :NICK
+ penalty += 3
+ when :ISON
+ penalty += 1
+ else # Unknown messages
+ penalty += 1
+ end
+ if penalty > 99
+ debug "Wow, more than 99 secs of penalty!"
+ penalty = 99
+ end
+ if penalty < 2
+ debug "Wow, less than 2 secs of penalty!"
+ penalty = 2
+ end
+ debug "penalty: #{penalty}"
+ return penalty
+ end
+end
+