class EventMachine::IRC::ConnectedClient
Attributes
channels[R]
nick[R]
realname[R]
state[R]
user[R]
Public Class Methods
new(server)
click to toggle source
# File lib/eventmachine/irc/server.rb, line 54 def initialize(server) @server = server @channels = Array.new @nick = nil @user = nil @pass = nil @last_ping = Time.now @last_pong = Time.now @state = {} @welcomed = false @nick_tries = 0 end
Public Instance Methods
handle_abort()
click to toggle source
# File lib/eventmachine/irc/server.rb, line 446 def handle_abort() handle_quit('aborted..') end
handle_away(msg)
click to toggle source
# File lib/eventmachine/irc/server.rb, line 356 def handle_away(msg) carp "handle away :#{msg}" if msg.nil? or msg =~ /^ *$/ @state.delete(:away) repl_unaway else @state[:away] = msg repl_nowaway end end
handle_connect()
click to toggle source
# File lib/eventmachine/irc/server.rb, line 463 def handle_connect reply :raw, "NOTICE AUTH :#{Server.config['version']} initialized, welcome." end
handle_eval(s)
click to toggle source
# File lib/eventmachine/irc/server.rb, line 454 def handle_eval(s) reply :raw, eval(s) end
handle_join(channel)
click to toggle source
# File lib/eventmachine/irc/server.rb, line 81 def handle_join(channel) @channels << channel end
handle_list(channel)
click to toggle source
# File lib/eventmachine/irc/server.rb, line 367 def handle_list(channel) reply :numeric, LISTSTART case channel.strip when /^#/ channel.split(/,/).each {|cname| c = Server.channel_store[cname.strip] reply :numeric, LIST, c.name, c.topic if c } else #older opera client sends LIST <1000 #we wont obey the boolean after list, but allow the listing #nonetheless Server.channel_store.each_channel {|c| reply :numeric, LIST, c.name, c.topic } end reply :numeric, LISTEND end
handle_mode(target, rest)
click to toggle source
# File lib/eventmachine/irc/server.rb, line 429 def handle_mode(target, rest) #TODO: dummy reply :mode, target, rest end
handle_names(channels, server)
click to toggle source
# File lib/eventmachine/irc/server.rb, line 403 def handle_names(channels, server) channels.split(/,/).each {|ch| send_nameslist(ch.strip) } end
handle_newconnect(nick)
click to toggle source
# File lib/eventmachine/irc/server.rb, line 137 def handle_newconnect(nick) @alive = true @nick = nick @host = Server.config['hostname'] @ver = Server.config['version'] @starttime = Server.config['starttime'] send_welcome if !@user.nil? end
handle_nick(nick)
click to toggle source
# File lib/eventmachine/irc/server.rb, line 85 def handle_nick(nick) carp "nick => #{nick}" if Server.user_store[nick].nil? userlist = {} if @nick.nil? handle_newconnect(nick) else userlist[nick] = self if self.nick != nick Server.user_store.delete(@nick) @nick = nick end Server.user_store << self #send the info to the world #get unique users. @channels.each { |c| Server.channel_store[c].each_user { |u| userlist[u.nick] = u } } userlist.values.each {|user| user.reply :nick, nick } @usermsg = ":#{@nick}!~#{@user}@#{@peername}" else #check if we are just nicking ourselves. unless Server.user_store[nick] == self #verify the connectivity of earlier guy reply :numeric, ERR_NICKNAMEINUSE, "* #{nick} ", "Nickname is already in use." @nick_tries += 1 if @nick_tries > Server.config['nick-tries'] carp "kicking spurious user #{nick} after #{@nick_tries} tries" handle_abort end end end @nick_tries = 0 end
handle_notice(target, msg)
click to toggle source
# File lib/eventmachine/irc/server.rb, line 300 def handle_notice(target, msg) case target.strip when CHANNEL channel= Server.channel_store[target] if !channel.nil? channel.notice(msg, self) else send_nonick(target) end else user = Server.user_store[target] if !user.nil? user.reply :notice, self.userprefix, user.nick, msg else send_nonick(target) end end end
handle_part(channel, msg)
click to toggle source
# File lib/eventmachine/irc/server.rb, line 319 def handle_part(channel, msg) if Server.channel_store.channels.include? channel if Server.channel_store[channel].part(self, msg) @channels.delete(channel) else send_notonchannel channel end else send_nochannel channel end end
handle_pass(pass)
click to toggle source
# File lib/eventmachine/irc/server.rb, line 146 def handle_pass(pass) @pass = pass end
handle_ping(pingmsg, rest)
click to toggle source
# File lib/eventmachine/irc/server.rb, line 270 def handle_ping(pingmsg, rest) reply :pong, pingmsg end
handle_pong(srv)
click to toggle source
# File lib/eventmachine/irc/server.rb, line 274 def handle_pong(srv) carp "got pong: #{srv}" end
handle_privmsg(target, msg)
click to toggle source
# File lib/eventmachine/irc/server.rb, line 278 def handle_privmsg(target, msg) case target.strip when CHANNEL channel= Server.channel_store[target] if !channel.nil? channel.privatemsg(msg, self) else send_nonick(target) end else user = Server.user_store[target] if !user.nil? if !user.state[:away].nil? repl_away(user.nick,user.state[:away]) end user.reply :privmsg, self.userprefix, user.nick, msg else send_nonick(target) end end end
handle_quit(msg)
click to toggle source
# File lib/eventmachine/irc/server.rb, line 331 def handle_quit(msg) #do this to avoid double quit due to 2 threads. return if !@alive @alive = false @channels.each do |channel| Server.channel_store[channel].quit(self, msg) end Server.user_store.delete(self.nick) carp "#{self.nick} #{msg}" @server.close_connection end
handle_reload(password)
click to toggle source
# File lib/eventmachine/irc/server.rb, line 443 def handle_reload(password) end
handle_topic(channel, topic)
click to toggle source
# File lib/eventmachine/irc/server.rb, line 343 def handle_topic(channel, topic) carp "handle topic for #{channel}:#{topic}" if topic.nil? or topic =~ /^ *$/ send_topic(channel) else begin Server.channel_store[channel].topic(topic,self) rescue Exception => e carp e end end end
handle_unknown(s)
click to toggle source
# File lib/eventmachine/irc/server.rb, line 458 def handle_unknown(s) carp "unknown:>#{s}<" reply :numeric, ERR_UNKNOWNCOMMAND,s, "Unknown command" end
handle_user(user, mode, unused, realname)
click to toggle source
# File lib/eventmachine/irc/server.rb, line 125 def handle_user(user, mode, unused, realname) @user = user @mode = mode @realname = realname @usermsg = ":#{@nick}!~#{@user}@#{@peername}" send_welcome if !@nick.nil? end
handle_userhost(nicks)
click to toggle source
# File lib/eventmachine/irc/server.rb, line 434 def handle_userhost(nicks) info = [] nicks.split(/,/).each {|nick| user = Server.user_store[nick] info << user.nick + '=-' + user.nick + '@' + user.peer } reply :numeric, USERHOST,"", info.join(' ') end
handle_version()
click to toggle source
# File lib/eventmachine/irc/server.rb, line 450 def handle_version() reply :numeric, VERSION,"#{Server.config['version']} Ruby IRCD", "" end
handle_who(mask, rest)
click to toggle source
# File lib/eventmachine/irc/server.rb, line 407 def handle_who(mask, rest) channel = Server.channel_store[mask] hopcount = 0 if channel.nil? #match against all users Server.user_store.each_user {|user| reply :numeric, WHOREPLY , "#{user.channels[0]} #{user.userprefix} #{user.host} #{Server.config['hostname']} #{user.nick} H" , "#{hopcount} #{user.realname}" if File.fnmatch?(mask, "#{user.host}.#{user.realname}.#{user.nick}") } reply :numeric, ENDOFWHO, mask, "End of /WHO list." else #get all users in the channel channel.each_user {|user| reply :numeric, WHOREPLY , "#{mask} #{user.userprefix} #{user.host} #{Server.config['hostname']} #{user.nick} H" , "#{hopcount} #{user.realname}" } reply :numeric, ENDOFWHO, mask, "End of /WHO list." end end
handle_whois(target,nicks)
click to toggle source
# File lib/eventmachine/irc/server.rb, line 386 def handle_whois(target,nicks) #ignore target for now. return reply(:numeric, NONICKNAMEGIVEN, "", "No nickname given") if nicks.strip.length == 0 nicks.split(/,/).each {|nick| nick.strip! user = Server.user_store[nick] if user reply :numeric, WHOISUSER, "#{user.nick} #{user.user} #{user.host} *", "#{user.realname}" reply :numeric, WHOISCHANNELS, user.nick, "#{user.channels.join(' ')}" repl_away user.nick, user.state[:away] if !user.state[:away].nil? reply :numeric, ENDOFWHOIS, user.nick, "End of /WHOIS list" else return send_nonick(nick) end } end
host()
click to toggle source
# File lib/eventmachine/irc/server.rb, line 67 def host # TODO: figure out how to do this with event machine return @peername end
mode()
click to toggle source
# File lib/eventmachine/irc/server.rb, line 133 def mode return @mode end
names(channel)
click to toggle source
# File lib/eventmachine/irc/server.rb, line 229 def names(channel) return Server.channel_store[channel].nicks end
raw(arg, abrt=false)
click to toggle source
# File lib/eventmachine/irc/server.rb, line 513 def raw(arg, abrt=false) begin carp "--> #{arg}" @server.send_data(arg.chomp + "\n") if !arg.nil? rescue Exception => e carp "<#{self.userprefix}>#{e.message}" #carp e.backtrace.join("\n") handle_abort() raise e if abrt end end
ready()
click to toggle source
# File lib/eventmachine/irc/server.rb, line 77 def ready return (!@pass.nil? && !@nick.nil?) end
receive_data(data)
click to toggle source
# File lib/eventmachine/irc/server.rb, line 525 def receive_data(data) carp "<-- '#{data.strip}'" s = if data =~ PREFIX $1 else data end case s when /^[ ]*$/ return when /^PASS +(.+)$/i handle_pass($1.strip) when /^NICK +(.+)$/i handle_nick($1.strip) #done when /^USER +([^ ]+) +([0-9]+) +([^ ]+) +:(.*)$/i handle_user($1, $2, $3, $4) #done when /^USER +([^ ]+) +([0-9]+) +([^ ]+) +:*(.*)$/i #opera does this. handle_user($1, $2, $3, $4) #done when /^USER ([^ ]+) +[^:]*:(.*)/i #chatzilla does this. handle_user($1, '', '', $3) #done when /^JOIN +(.+)$/i handle_join($1) #done when /^PING +([^ ]+) *(.*)$/i handle_ping($1, $2) #done when /^PONG +:(.+)$/i , /^PONG +(.+)$/i handle_pong($1) when /^PRIVMSG +([^ ]+) +:(.*)$/i handle_privmsg($1, $2) #done when /^NOTICE +([^ ]+) +(.*)$/i handle_notice($1, $2) #done when /^PART :+([^ ]+) *(.*)$/i #some clients require this. handle_part($1, $2) #done when /^PART +([^ ]+) *(.*)$/i handle_part($1, $2) #done when /^QUIT :(.*)$/i handle_quit($1) #done when /^QUIT *(.*)$/i handle_quit($1) #done when /^TOPIC +([^ ]+) *:*(.*)$/i handle_topic($1, $2) #done when /^AWAY +:(.*)$/i handle_away($1) when /^AWAY +(.*)$/i #for opera handle_away($1) when /^:*([^ ])* *AWAY *$/i handle_away(nil) when /^AWAY\s*$/i handle_away(nil) when /^LIST *(.*)$/i handle_list($1) when /^WHOIS +([^ ]+) +(.+)$/i handle_whois($1,$2) when /^WHOIS +([^ ]+)$/i handle_whois(nil,$1) when /^WHO +([^ ]+) *(.*)$/i handle_who($1, $2) when /^NAMES +([^ ]+) *(.*)$/i handle_names($1, $2) when /^MODE +([^ ]+) *(.*)$/i handle_mode($1, $2) when /^USERHOST +:(.+)$/i #besirc does this (not accourding to RFC 2812) handle_userhost($1) when /^USERHOST +(.+)$/i handle_userhost($1) when /^RELOAD +(.+)$/i handle_reload($1) when /^VERSION *$/i handle_version() when /^EVAL (.*)$/i #strictly for debug handle_eval($1) else handle_unknown(s) end end
repl_away(nick, msg)
click to toggle source
# File lib/eventmachine/irc/server.rb, line 188 def repl_away(nick, msg) reply :numeric, AWAY, nick, msg end
repl_bounce(sever, port)
click to toggle source
# File lib/eventmachine/irc/server.rb, line 179 def repl_bounce(sever, port) reply :numeric, BOUNCE ,"Try server #{server}, port #{port}" end
repl_created()
click to toggle source
# File lib/eventmachine/irc/server.rb, line 171 def repl_created reply :numeric, CREATED, @nick, "This server was created #{@starttime}" end
repl_ison()
click to toggle source
# File lib/eventmachine/irc/server.rb, line 183 def repl_ison() #XXX TODO reply :numeric, ISON,"notimpl" end
repl_mode()
click to toggle source
# File lib/eventmachine/irc/server.rb, line 206 def repl_mode() end
repl_motd()
click to toggle source
# File lib/eventmachine/irc/server.rb, line 200 def repl_motd() reply :numeric, MOTDSTART,'', "- Message of the Day" reply :numeric, MOTD,'', "- Do the dance see the source" reply :numeric, ENDOFMOTD,'', "- End of /MOTD command." end
repl_myinfo()
click to toggle source
# File lib/eventmachine/irc/server.rb, line 175 def repl_myinfo reply :numeric, MYINFO, @nick, "#{@host} #{@ver} #{@server.usermodes} #{@server.channelmodes}" end
repl_nowaway()
click to toggle source
# File lib/eventmachine/irc/server.rb, line 196 def repl_nowaway() reply :numeric, NOWAWAY, @nick,"You have been marked as being away" end
repl_unaway()
click to toggle source
# File lib/eventmachine/irc/server.rb, line 192 def repl_unaway() reply :numeric, UNAWAY, @nick,"You are no longer marked as being away" end
repl_welcome()
click to toggle source
# File lib/eventmachine/irc/server.rb, line 162 def repl_welcome client = "#{@nick}!#{@user}@#{@peername}" reply :numeric, WELCOME, @nick, "Welcome to this IRC server #{client}" end
repl_yourhost()
click to toggle source
# File lib/eventmachine/irc/server.rb, line 167 def repl_yourhost reply :numeric, YOURHOST, @nick, "Your host is #{@host}, running version #{@ver}" end
reply(method, *args)
click to toggle source
# File lib/eventmachine/irc/server.rb, line 467 def reply(method, *args) case method when :raw arg = *args raw arg when :ping host = *args raw "PING :#{host}" when :pong msg = *args # according to rfc 2812 the PONG must be of #PONG csd.bu.edu tolsun.oulu.fi # PONG message from csd.bu.edu to tolsun.oulu.fi # ie no host at the begining raw "PONG #{@host} #{@peername} :#{msg}" when :join user,channel = args raw "#{user} JOIN :#{channel}" when :part user,channel,msg = args raw "#{user} PART #{channel} :#{msg}" when :quit user,msg = args raw "#{user} QUIT :#{msg}" when :privmsg usermsg, channel, msg = args raw "#{usermsg} PRIVMSG #{channel} :#{msg}" when :notice usermsg, channel, msg = args raw "#{usermsg} NOTICE #{channel} :#{msg}" when :topic usermsg, channel, msg = args raw "#{usermsg} TOPIC #{channel} :#{msg}" when :nick nick = *args raw "#{@usermsg} NICK :#{nick}" when :mode nick, rest = args raw "#{@usermsg} MODE #{nick} :#{rest}" when :numeric numeric,msg,detail = args server = Server.config['hostname'] raw ":#{server} #{'%03d'%numeric} #{@nick} #{msg} :#{detail}" end end
send_nameslist(channel)
click to toggle source
# File lib/eventmachine/irc/server.rb, line 233 def send_nameslist(channel) c = Server.channel_store[channel] if c.nil? carp "names failed :#{c}" return end names = [] c.each_user {|user| names << c.mode(user) + user.nick if user.nick } reply :numeric, NAMREPLY,"= #{c.name}","#{names.join(' ')}" reply :numeric, ENDOFNAMES,"#{c.name} ","End of /NAMES list." end
send_nochannel(channel)
click to toggle source
# File lib/eventmachine/irc/server.rb, line 221 def send_nochannel(channel) reply :numeric, ERR_NOSUCHCHANNEL, channel, "That channel doesn't exist" end
send_nonick(nick)
click to toggle source
# File lib/eventmachine/irc/server.rb, line 217 def send_nonick(nick) reply :numeric, ERR_NOSUCHNICK, nick, "No such nick/channel" end
send_notonchannel(channel)
click to toggle source
# File lib/eventmachine/irc/server.rb, line 225 def send_notonchannel(channel) reply :numeric, ERR_NOTONCHANNEL, channel, "Not a member of that channel" end
send_ping()
click to toggle source
# File lib/eventmachine/irc/server.rb, line 247 def send_ping() reply :ping, "#{Server.config['hostname']}" end
send_topic(channel)
click to toggle source
# File lib/eventmachine/irc/server.rb, line 209 def send_topic(channel) if Server.channel_store[channel] reply :numeric, TOPIC,channel, "#{Server.channel_store[channel].topic}" else send_notonchannel channel end end
send_welcome()
click to toggle source
# File lib/eventmachine/irc/server.rb, line 150 def send_welcome if !@welcomed repl_welcome repl_yourhost repl_created repl_myinfo repl_motd repl_mode @welcomed = true end end
userprefix()
click to toggle source
# File lib/eventmachine/irc/server.rb, line 72 def userprefix # Where is this defined? return @usermsg end