- Timestamp:
- Nov 2, 2021, 5:25:43 PM (4 years ago)
- Location:
- trunk
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/downstream.go
r659 r660 237 237 "USERLEN": true, 238 238 "UTF8ONLY": true, 239 "WHOX": true, 239 240 } 240 241 … … 1156 1157 if dc.network != nil { 1157 1158 isupport = append(isupport, fmt.Sprintf("BOUNCER_NETID=%v", dc.network.ID)) 1159 } 1160 1161 if dc.network == nil && dc.caps["soju.im/bouncer-networks"] { 1162 isupport = append(isupport, "WHOX") 1158 1163 } 1159 1164 … … 1883 1888 } 1884 1889 } 1890 // For WHOX docs, see: 1891 // - http://faerion.sourceforge.net/doc/irc/whox.var 1892 // - https://github.com/quakenet/snircd/blob/master/doc/readme.who 1893 // Note, many features aren't widely implemented, such as flags and mask2 1885 1894 case "WHO": 1886 1895 if len(msg.Params) == 0 { … … 1894 1903 } 1895 1904 1896 // TODO: support WHO masks 1897 entity := msg.Params[0] 1898 entityCM := casemapASCII(entity) 1899 1900 if dc.network == nil && entityCM == dc.nickCM { 1905 // Clients will use the first mask to match RPL_ENDOFWHO 1906 endOfWhoToken := msg.Params[0] 1907 1908 // TODO: add support for WHOX mask2 1909 mask := msg.Params[0] 1910 var options string 1911 if len(msg.Params) > 1 { 1912 options = msg.Params[1] 1913 } 1914 1915 optionsParts := strings.SplitN(options, "%", 2) 1916 // TODO: add support for WHOX flags in optionsParts[0] 1917 var fields, whoxToken string 1918 if len(optionsParts) == 2 { 1919 optionsParts := strings.SplitN(optionsParts[1], ",", 2) 1920 fields = strings.ToLower(optionsParts[0]) 1921 if len(optionsParts) == 2 && strings.Contains(fields, "t") { 1922 whoxToken = optionsParts[1] 1923 } 1924 } 1925 1926 // TODO: support mixed bouncer/upstream WHO queries 1927 maskCM := casemapASCII(mask) 1928 if dc.network == nil && maskCM == dc.nickCM { 1901 1929 // TODO: support AWAY (H/G) in self WHO reply 1902 1930 flags := "H" … … 1904 1932 flags += "*" 1905 1933 } 1906 dc.SendMessage(&irc.Message{ 1907 Prefix: dc.srv.prefix(), 1908 Command: irc.RPL_WHOREPLY, 1909 Params: []string{dc.nick, "*", dc.user.Username, dc.hostname, dc.srv.Hostname, dc.nick, flags, "0 " + dc.realname}, 1910 }) 1934 info := whoxInfo{ 1935 Token: whoxToken, 1936 Username: dc.user.Username, 1937 Hostname: dc.hostname, 1938 Server: dc.srv.Hostname, 1939 Nickname: dc.nick, 1940 Flags: flags, 1941 Realname: dc.realname, 1942 } 1943 dc.SendMessage(generateWHOXReply(dc.srv.prefix(), dc.nick, fields, &info)) 1911 1944 dc.SendMessage(&irc.Message{ 1912 1945 Prefix: dc.srv.prefix(), 1913 1946 Command: irc.RPL_ENDOFWHO, 1914 Params: []string{dc.nick, dc.nick, "End of /WHO list"},1947 Params: []string{dc.nick, endOfWhoToken, "End of /WHO list"}, 1915 1948 }) 1916 1949 return nil 1917 1950 } 1918 if entityCM == serviceNickCM { 1919 dc.SendMessage(&irc.Message{ 1920 Prefix: dc.srv.prefix(), 1921 Command: irc.RPL_WHOREPLY, 1922 Params: []string{serviceNick, "*", servicePrefix.User, servicePrefix.Host, dc.srv.Hostname, serviceNick, "H*", "0 " + serviceRealname}, 1923 }) 1951 if maskCM == serviceNickCM { 1952 info := whoxInfo{ 1953 Token: whoxToken, 1954 Username: servicePrefix.User, 1955 Hostname: servicePrefix.Host, 1956 Server: dc.srv.Hostname, 1957 Nickname: serviceNick, 1958 Flags: "H*", 1959 Realname: serviceRealname, 1960 } 1961 dc.SendMessage(generateWHOXReply(dc.srv.prefix(), dc.nick, fields, &info)) 1924 1962 dc.SendMessage(&irc.Message{ 1925 1963 Prefix: dc.srv.prefix(), 1926 1964 Command: irc.RPL_ENDOFWHO, 1927 Params: []string{dc.nick, serviceNick, "End of /WHO list"},1965 Params: []string{dc.nick, endOfWhoToken, "End of /WHO list"}, 1928 1966 }) 1929 1967 return nil 1930 1968 } 1931 1969 1932 uc, upstreamName, err := dc.unmarshalEntity(entity) 1970 // TODO: properly support WHO masks 1971 uc, upstreamMask, err := dc.unmarshalEntity(mask) 1933 1972 if err != nil { 1934 1973 return err 1935 1974 } 1936 1975 1937 var params []string 1938 if len(msg.Params) == 2 { 1939 params = []string{upstreamName, msg.Params[1]} 1940 } else { 1941 params = []string{upstreamName} 1976 params := []string{upstreamMask} 1977 if options != "" { 1978 params = append(params, options) 1942 1979 } 1943 1980 -
trunk/irc.go
r636 r660 18 18 rpl_creationtime = "329" 19 19 rpl_topicwhotime = "333" 20 rpl_whospcrpl = "354" 20 21 err_invalidcapcmd = "410" 21 22 ) … … 683 684 } 684 685 } 686 687 type whoxInfo struct { 688 Token string 689 Username string 690 Hostname string 691 Server string 692 Nickname string 693 Flags string 694 Account string 695 Realname string 696 } 697 698 func generateWHOXReply(prefix *irc.Prefix, nick, fields string, info *whoxInfo) *irc.Message { 699 if fields == "" { 700 return &irc.Message{ 701 Prefix: prefix, 702 Command: irc.RPL_WHOREPLY, 703 Params: []string{nick, "*", info.Username, info.Hostname, info.Server, info.Nickname, info.Flags, "0 " + info.Realname}, 704 } 705 } 706 707 fieldSet := make(map[byte]bool) 708 for i := 0; i < len(fields); i++ { 709 fieldSet[fields[i]] = true 710 } 711 712 var params []string 713 if fieldSet['t'] { 714 params = append(params, info.Token) 715 } 716 if fieldSet['c'] { 717 params = append(params, "*") 718 } 719 if fieldSet['u'] { 720 params = append(params, info.Username) 721 } 722 if fieldSet['i'] { 723 params = append(params, "255.255.255.255") 724 } 725 if fieldSet['h'] { 726 params = append(params, info.Hostname) 727 } 728 if fieldSet['s'] { 729 params = append(params, info.Server) 730 } 731 if fieldSet['n'] { 732 params = append(params, info.Nickname) 733 } 734 if fieldSet['f'] { 735 params = append(params, info.Flags) 736 } 737 if fieldSet['d'] { 738 params = append(params, "0") 739 } 740 if fieldSet['l'] { // idle time 741 params = append(params, "0") 742 } 743 if fieldSet['a'] { 744 account := "0" // WHOX uses "0" to mean "no account" 745 if info.Account != "" && info.Account != "*" { 746 account = info.Account 747 } 748 params = append(params, account) 749 } 750 if fieldSet['o'] { 751 params = append(params, "0") 752 } 753 if fieldSet['r'] { 754 params = append(params, info.Realname) 755 } 756 757 return &irc.Message{ 758 Prefix: prefix, 759 Command: rpl_whospcrpl, 760 Params: append([]string{nick}, params...), 761 } 762 } -
trunk/upstream.go
r655 r660 1453 1453 case irc.RPL_YOURHOST, irc.RPL_CREATED: 1454 1454 // Ignore 1455 case rpl_whospcrpl: 1456 // Not supported in multi-upstream mode, forward as-is 1457 uc.forEachDownstream(func(dc *downstreamConn) { 1458 dc.SendMessage(msg) 1459 }) 1455 1460 case irc.RPL_LUSERCLIENT, irc.RPL_LUSEROP, irc.RPL_LUSERUNKNOWN, irc.RPL_LUSERCHANNELS, irc.RPL_LUSERME: 1456 1461 fallthrough
Note:
See TracChangeset
for help on using the changeset viewer.