Changeset 6149

Show
Ignore:
Timestamp:
02/04/08 12:48:59 (5 years ago)
Author:
cho45
Message:

lang/ruby/net-irc/trunk/examples/lig.rb:

  • system:leave などが送られてこなくても確実にルームのユーザを更新できるように
  • system:{enter,leave,nicknamge_changed} はつかわず、常に occupants list を処理するように
  • これにより
    • anonymous から認証ユーザへの昇格とニックネームの変更を同一にあつかえるように
    • JOIN/PART メッセージが流れまくって邪魔なのを阻止 (あくまで IRC クライアント側での表示)
    • 副作用として JOIN/PART の流れるタイミングがズレる
  • ついでにルームに入ったときに RPL_NAME* することで JOIN がたくさんでるのを阻止
Files:
1 modified

Legend:

Unmodified
Added
Removed
  • lang/ruby/net-irc/trunk/examples/lig.rb

    r6138 r6149  
    115115 
    116116                u_id, o_id, prefix = *make_ids(@user_info) 
     117                @user_info["prefix"] = prefix 
    117118                post @prefix, NICK, prefix.nick 
    118119        end 
     
    129130                nick = m.params[0] 
    130131                chan = nil 
    131                 pref = nil 
     132                info = nil 
    132133 
    133134                @channels.each do |k, v| 
    134135                        if v[:users].key?(nick) 
    135136                                chan = k 
    136                                 pref = v[:users][nick] 
     137                                info = v[:users][nick] 
    137138                                break 
    138139                        end 
     
    140141 
    141142                if chan 
    142                         real_name   = pref 
     143                        prefix      = info["prefix"] 
     144                        real_name   = prefix 
    143145                        server_info = "Lingr" 
    144                         channels    = [chan] 
     146                        channels    = [info["client_type"] == "human" ? "@#{chan}" : chan] 
    145147                        u_id, o_id, me = *make_ids(@user_info) 
    146148 
    147                         post nil, RPL_WHOISUSER,     me.nick, pref.nick, pref.user, pref.host, "*", real_name 
    148                         post nil, RPL_WHOISSERVER,   me.nick, pref.nick, pref.nick, pref.host, server_info 
    149                         # post nil, RPL_WHOISOPERATOR, me.nick, pref.nick, "is an IRC operator" 
    150                         # post nil, RPL_WHOISIDLE,     me.nick, pref.nick, idle, "seconds idle" 
    151                         post nil, RPL_WHOISCHANNELS, me.nick, pref.nick, channels.map {|i| "@#{i}" }.join(" ") 
    152                         post nil, RPL_ENDOFWHOIS,    me.nick, pref.nick, "End of WHOIS list" 
     149                        post nil, RPL_WHOISUSER,     me.nick, prefix.nick, prefix.user, prefix.host, "*", real_name 
     150                        post nil, RPL_WHOISSERVER,   me.nick, prefix.nick, prefix.nick, prefix.host, server_info 
     151                        # post nil, RPL_WHOISOPERATOR, me.nick, prefix.nick, "is an IRC operator" 
     152                        # post nil, RPL_WHOISIDLE,     me.nick, prefix.nick, idle, "seconds idle" 
     153                        post nil, RPL_WHOISCHANNELS, me.nick, prefix.nick, channels.join(" ") 
     154                        post nil, RPL_ENDOFWHOIS,    me.nick, prefix.nick, "End of WHOIS list" 
    153155                else 
    154156                        post nil, ERR_NOSUCHNICK, me.nick, nick, "No such nick/channel" 
     
    164166                res  = @lingr.get_room_info(info[:chan_id], nil, info[:password]) 
    165167                res["occupants"].each do |o| 
     168                        next unless o["nickname"] 
    166169                        u_id, o_id, prefix = *make_ids(o) 
    167                         post nil, RPL_WHOREPLY, me.nick, channel, o_id, "lingr.com", "lingr.com", prefix.nick, "H*@", "0 #{o["description"].to_s.gsub(/\s+/, " ")}" 
     170                        op = (o["client_type"] == "human") ? "@" : "" 
     171                        post nil, RPL_WHOREPLY, me.nick, channel, o_id, "lingr.com", "lingr.com", prefix.nick, "H*#{op}", "0 #{o["description"].to_s.gsub(/\s+/, " ")}" 
    168172                end 
    169173                post nil, RPL_ENDOFWHO, me.nick, channel 
     
    215219        def create_observer(channel, response) 
    216220                Thread.start(channel, response) do |chan, res| 
    217                         myu_id, myo_id, myprefix = *make_ids(@user_info) 
     221                        myprefix = @user_info["prefix"] 
    218222                        post server_name, TOPIC, chan, "#{res["room"]["url"]} #{res["room"]["description"]}" 
    219223                        @channels[chan.downcase] = { 
     
    223227                                :chan_id  => res["room"]["id"], 
    224228                                :password => res["password"], 
    225                                 :users    => { myprefix.nick => myprefix }, 
     229                                :users    => res["occupants"].reject {|i| i["nickname"].nil? }.inject({}) {|r,i| 
     230                                        _, _, i["prefix"] = make_ids(i) 
     231                                        r.update(i["prefix"].nick => i) 
     232                                }, 
    226233                                :hcounter => 0, 
    227234                                :observer => Thread.current, 
     
    229236                        post myprefix, JOIN, channel 
    230237                        post server_name, MODE, channel, "+o", myprefix.nick 
     238                        post nil, RPL_NAMREPLY,   myprefix.nick, "=", chan, @channels[chan.downcase][:users].map{|k,v| 
     239                                p v 
     240                                v["client_type"] == "human" ? "@#{k}" : k 
     241                        }.join(" ") 
     242                        post nil, RPL_ENDOFNAMES, myprefix.nick, chan, "End of NAMES list" 
     243 
    231244                        first = true 
     245                        info = @channels[chan.downcase] 
    232246                        while true 
    233247                                begin 
    234                                         info = @channels[chan.downcase] 
    235248                                        res = @lingr.observe_room info[:ticket], info[:counter] 
    236249                                        @log.debug "observe_room<#{chan}> returned" 
    237250 
    238251                                        info[:counter] = res["counter"] if res["counter"] 
     252 
    239253                                        (res["messages"] || []).each do |m| 
    240254                                                next if m["id"].to_i <= info[:hcounter] 
     
    252266                                                        # TODO 
    253267                                                        post prefix, PRIVMSG, chan, "\x01ACTION Sent private: #{m["text"]}\x01" unless info[:o_id] == o_id 
    254                                                 when "system:enter" 
    255                                                         unless prefix.nick == myprefix.nick 
    256                                                                 post prefix, JOIN, chan 
    257                                                                 if m["client_type"] == "human" 
    258                                                                         post server_name, MODE, chan, "+o", prefix.nick 
    259                                                                 end 
    260                                                                 info[:users][prefix.nick] = prefix 
    261                                                         end 
    262                                                 when "system:leave" 
    263                                                         unless prefix.nick == myprefix.nick 
    264                                                                 post prefix, PART, chan 
    265                                                                 info[:users].delete(prefix.nick) 
    266                                                         end 
    267                                                 when "system:nickname_change" 
    268                                                         m["nickname"] = m["new_nickname"] 
    269                                                         _, _, newprefix = *make_ids(m) 
    270                                                         post prefix, NICK, newprefix.nick 
    271                                                         info[:users].delete prefix.nick 
    272                                                         info[:users][newprefix.nick] = newprefix 
     268## process as occupants list. 
     269#                                               when "system:enter" 
     270#                                                       unless prefix.nick == myprefix.nick 
     271#                                                               post prefix, JOIN, chan 
     272#                                                               if m["client_type"] == "human" 
     273#                                                                       post server_name, MODE, chan, "+o", prefix.nick 
     274#                                                               end 
     275#                                                               info[:users][prefix.nick] = m.merge("prefix" => prefix) 
     276#                                                       end 
     277#                                               when "system:leave" 
     278#                                                       unless prefix.nick == myprefix.nick 
     279#                                                               post prefix, PART, chan 
     280#                                                               info[:users].delete(prefix.nick) 
     281#                                                       end 
     282#                                               when "system:nickname_change" 
     283#                                                       m["nickname"] = m["new_nickname"] 
     284#                                                       _, _, newprefix = *make_ids(m) 
     285#                                                       post prefix, NICK, newprefix.nick 
     286#                                                       info[:users].delete prefix.nick 
     287#                                                       info[:users][newprefix.nick] = m.merge("prefix" => newprefix) 
    273288                                                when "system:broadcast" 
    274289                                                        post "system.broadcast",  NOTICE, chan, m["text"] 
     
    279294 
    280295                                        if res["occupants"] 
    281                                                 res["occupants"].each do |o| 
    282                                                         if o["nickname"] 
    283                                                                 u_id, o_id, prefix = make_ids(o) 
    284                                                                 o["user_id"] = nil 
    285                                                                 _, _, anonprefix   = make_ids(o) 
    286  
    287                                                                 unless info[:users].key?(prefix.nick) 
    288                                                                         if info[:users].key?(anonprefix.nick) 
    289                                                                                 # when non-auth user be promoted to auth user. 
    290                                                                                 post anonprefix, NICK, prefix.nick 
    291                                                                                 info[:users].delete anonprefix.nick 
    292                                                                         else 
    293                                                                                 post prefix, JOIN, chan 
    294                                                                                 if o["client_type"] == "human" 
    295                                                                                         post server_name, MODE, chan, "+o", prefix.nick 
    296                                                                                 end 
    297                                                                         end 
    298                                                                         info[:users][prefix.nick] = prefix 
    299                                                                 end 
     296                                                enter = [], leave = [] 
     297                                                newusers = res["occupants"].reject {|i| i["nickname"].nil? }.inject({}) {|r,i| 
     298                                                        _, _, i["prefix"] = make_ids(i) 
     299                                                        r.update(i["prefix"].nick => i) 
     300                                                } 
     301 
     302 
     303                                                nickchange = newusers.inject({:new => [], :old => []}) {|r,(k,new)| 
     304                                                        old = info[:users].find {|l,old| 
     305                                                                # same occupant_id and different nickname 
     306                                                                # when nickname was changed and when un-authed user promoted to authed user. 
     307                                                                new["prefix"] != old["prefix"] && new["id"] == old["id"] 
     308                                                        } 
     309                                                        p old 
     310                                                        if old 
     311                                                                old = old[1] 
     312                                                                post old["prefix"], NICK, new["prefix"].nick 
     313                                                                r[:old] << old["prefix"].nick 
     314                                                                r[:new] << new["prefix"].nick 
     315                                                        end 
     316                                                        r 
     317                                                } 
     318 
     319                                                entered = newusers.keys - info[:users].keys - nickchange[:new] 
     320                                                leaved  = info[:users].keys - newusers.keys - entered - nickchange[:old] 
     321 
     322                                                leaved.each do |leave| 
     323                                                        leave = info[:users][leave] 
     324                                                        post leave["prefix"], PART, chan, "" 
     325                                                end 
     326 
     327                                                entered.each do |enter| 
     328                                                        enter  = newusers[enter] 
     329                                                        prefix = enter["prefix"] 
     330                                                        post prefix, JOIN, chan 
     331                                                        if enter["client_type"] == "human" 
     332                                                                post server_name, MODE, chan, "+o", prefix.nick 
    300333                                                        end 
    301334                                                end 
     335 
     336 
     337                                                info[:users] = newusers 
    302338                                        end 
     339 
     340 
    303341                                        first = false 
    304342                                rescue Lingr::Client::APIError => e 
     
    318356                                        end 
    319357                                end 
     358                                sleep 1 
    320359                        end 
    321360                end 
     
    335374                u_id  = o["user_id"] || "anon" 
    336375                o_id  = o["occupant_id"] || o["id"] 
    337                 nick  = (o["default_nickname"] || o["nickname"]).gsub(/\s+/, "")  
     376                nick  = (o["default_nickname"] || o["nickname"]).gsub(/\s+/, "") 
    338377                if o["user_id"] == @user_info["user_id"] 
    339378                        nick << "|#{o["user_id"]}"