Changeset 127 in code for trunk


Ignore:
Timestamp:
Mar 19, 2020, 11:29:03 PM (5 years ago)
Author:
delthas
Message:

Add WHO support

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/downstream.go

    r125 r127  
    170170}
    171171
    172 func (dc *downstreamConn) unmarshalChannel(name string) (*upstreamConn, string, error) {
     172func (dc *downstreamConn) unmarshalEntity(name string) (*upstreamConn, string, error) {
    173173        if uc := dc.upstream(); uc != nil {
    174174                return uc, name, nil
    175175        }
    176176
    177         network := ""
     177        var conn *upstreamConn
    178178        if i := strings.LastIndexByte(name, '/'); i >= 0 {
    179                 network = name[i+1:]
     179                network := name[i+1:]
    180180                name = name[:i]
    181         }
    182 
    183         if network != "" {
    184                 var conn *upstreamConn
     181
    185182                dc.forEachUpstream(func(uc *upstreamConn) {
    186183                        if network != uc.network.GetName() {
     
    189186                        conn = uc
    190187                })
    191                 return conn, name, nil
    192         }
    193 
    194         var channel *upstreamChannel
    195         var err error
    196         dc.forEachUpstream(func(uc *upstreamConn) {
    197                 if err != nil {
    198                         return
    199                 }
    200                 if ch, ok := uc.channels[name]; ok {
    201                         if channel != nil {
    202                                 err = fmt.Errorf("ambiguous channel name %q", name)
    203                         } else {
    204                                 channel = ch
    205                         }
    206                 }
    207         })
    208         if channel == nil {
     188        }
     189
     190        if conn == nil {
    209191                return nil, "", ircError{&irc.Message{
    210192                        Command: irc.ERR_NOSUCHCHANNEL,
     
    212194                }}
    213195        }
    214         return channel.conn, channel.Name, nil
     196        return conn, name, nil
    215197}
    216198
     
    844826                }
    845827
    846                 uc, upstreamName, err := dc.unmarshalChannel(name)
     828                uc, upstreamName, err := dc.unmarshalEntity(name)
    847829                if err != nil {
    848830                        return ircError{&irc.Message{
     
    886868
    887869                if msg.Prefix.Name != name {
    888                         uc, upstreamName, err := dc.unmarshalChannel(name)
     870                        uc, upstreamName, err := dc.unmarshalEntity(name)
    889871                        if err != nil {
    890872                                return err
     
    934916                        }
    935917                }
     918        case "WHO":
     919                if len(msg.Params) == 0 {
     920                        // TODO: support WHO without parameters
     921                        dc.SendMessage(&irc.Message{
     922                                Prefix:  dc.srv.prefix(),
     923                                Command: irc.RPL_ENDOFWHO,
     924                                Params:  []string{dc.nick, "*", "End of /WHO list."},
     925                        })
     926                        return nil
     927                }
     928
     929                // TODO: support WHO masks
     930                entity := msg.Params[0]
     931
     932                uc, upstreamName, err := dc.unmarshalEntity(entity)
     933                if err != nil {
     934                        return err
     935                }
     936
     937                var params []string
     938                if len(msg.Params) == 2 {
     939                        params = []string{upstreamName, msg.Params[1]}
     940                } else {
     941                        params = []string{upstreamName}
     942                }
     943
     944                uc.SendMessage(&irc.Message{
     945                        Command: "WHO",
     946                        Params:  params,
     947                })
    936948        case "PRIVMSG":
    937949                var targetsStr, text string
     
    946958                        }
    947959
    948                         uc, upstreamName, err := dc.unmarshalChannel(name)
     960                        uc, upstreamName, err := dc.unmarshalEntity(name)
    949961                        if err != nil {
    950962                                return err
  • trunk/upstream.go

    r125 r127  
    558558                        forwardChannel(dc, ch)
    559559                })
     560        case irc.RPL_WHOREPLY:
     561                var channel, username, host, server, nick, mode, trailing string
     562                if err := parseMessageParams(msg, nil, &channel, &username, &host, &server, &nick, &mode, &trailing); err != nil {
     563                        return err
     564                }
     565
     566                parts := strings.SplitN(trailing, " ", 2)
     567                if len(parts) != 2 {
     568                        return fmt.Errorf("received malformed RPL_WHOREPLY: wrong trailing parameter: %s", trailing)
     569                }
     570                realname := parts[1]
     571                hops, err := strconv.Atoi(parts[0])
     572                if err != nil {
     573                        return fmt.Errorf("received malformed RPL_WHOREPLY: wrong hop count: %s", parts[0])
     574                }
     575                hops++
     576
     577                trailing = strconv.Itoa(hops) + " " + realname
     578
     579                uc.forEachDownstream(func(dc *downstreamConn) {
     580                        channel := channel
     581                        if channel != "*" {
     582                                channel = dc.marshalChannel(uc, channel)
     583                        }
     584                        nick := dc.marshalNick(uc, nick)
     585                        dc.SendMessage(&irc.Message{
     586                                Prefix:  dc.srv.prefix(),
     587                                Command: irc.RPL_WHOREPLY,
     588                                Params:  []string{dc.nick, channel, username, host, server, nick, mode, trailing},
     589                        })
     590                })
     591        case irc.RPL_ENDOFWHO:
     592                var name string
     593                if err := parseMessageParams(msg, nil, &name); err != nil {
     594                        return err
     595                }
     596
     597                uc.forEachDownstream(func(dc *downstreamConn) {
     598                        name := name
     599                        if name != "*" {
     600                                // TODO: support WHO masks
     601                                name = dc.marshalEntity(uc, name)
     602                        }
     603                        dc.SendMessage(&irc.Message{
     604                                Prefix:  dc.srv.prefix(),
     605                                Command: irc.RPL_ENDOFWHO,
     606                                Params:  []string{dc.nick, name, "End of /WHO list."},
     607                        })
     608                })
    560609        case "PRIVMSG":
    561610                if msg.Prefix == nil {
Note: See TracChangeset for help on using the changeset viewer.