Class: Irc::Server
- Inherits:
-
Object
- Object
- Irc::Server
- Defined in:
- /home/apoc/projects/ruby/rbot/lib/rbot/irc.rb
Overview
An IRC Server represents the Server the client is connected to.
Instance Attribute Summary (collapse)
-
- (Object) capabilities
readonly
Returns the value of attribute capabilities.
-
- (Object) chanmodes
readonly
Returns the value of attribute chanmodes.
-
- (Object) channels
readonly
Returns the value of attribute channels.
-
- (Object) hostname
readonly
Returns the value of attribute hostname.
-
- (Object) supports
readonly
Returns the value of attribute supports.
-
- (Object) usermodes
readonly
Returns the value of attribute usermodes.
-
- (Object) users
readonly
Returns the value of attribute users.
-
- (Object) version
readonly
Returns the value of attribute version.
Instance Method Summary (collapse)
-
- (Object) casemap
Returns the casemap of the server.
-
- (Object) channel(str)
Returns the Channel with the given name on the server, creating it if necessary.
-
- (Object) channel_names
TODO Ho.
-
- (Object) clear
Clears the server.
-
- (Object) delete_channel(name)
Remove Channel name from the list of Channels.
-
- (Object) delete_user(someuser)
Remove User someuser from the list of Users.
-
- (Object) delete_user_from_channel(user, channel)
Deletes User user from Channel channel.
-
- (Object) find_users(mask)
Finds all Users on server whose Netmask matches mask.
-
- (Object) get_channel(name)
(also: #get_chan)
Returns the channel with name name, if available.
-
- (Object) get_user(nick)
Returns the user with nick nick, if available.
-
- (Boolean) has_channel?(name)
(also: #has_chan?)
Checks if the receiver already has a channel with the given name.
-
- (Boolean) has_user?(nick)
Checks if the receiver already has a user with the given nick.
-
- (Server) initialize
constructor
Create a new Server, with all instance variables reset to nil (for scalar variables), empty channel and user lists and @supports initialized to the default values for all known supported features.
- - (Object) inspect
-
- (Object) mode_for_prefix(pfx)
Convert a prefix (@, +, %, …) to the corresponding mode (o, v, h, …).
-
- (Object) new_channel(name, topic = nil, users = [], fails = true)
Create a new Channel object bound to the receiver and add it to the list of Channels on the receiver, unless the channel was present already.
-
- (Object) new_netmask(str)
Create a new Netmask object with the appropriate casemap.
-
- (Object) new_user(str, fails = true)
Create a new User object bound to the receiver and add it to the list of Users on the receiver, unless the User was present already.
-
- (Object) parse_isupport(line)
This method is used to parse a 005 RPL_ISUPPORT line.
-
- (Object) parse_my_info(line)
This method is used to parse a 004 RPL_MY_INFO line.
-
- (Object) prefix_for_mode(mode)
Convert a mode (o, v, h, …) to the corresponding prefix (@, +, %, …).
-
- (Object) reset_capabilities
Resets the server capabilities.
-
- (Object) reset_lists
Resets the Channel and User list.
- - (Object) to_s
-
- (Object) user(str)
Returns the User with the given Netmask on the server, creating it if necessary.
-
- (Object) user_nicks
TODO Ho.
-
- (Object) user_or_channel(name)
Returns the actual User or Channel object matching name.
-
- (Boolean) user_or_channel?(name)
Returns User or Channel depending on what name can be a name of.
Constructor Details
- (Server) initialize
Create a new Server, with all instance variables reset to nil (for scalar variables), empty channel and user lists and @supports initialized to the default values for all known supported features.
1566 1567 1568 1569 1570 1571 1572 1573 1574 |
# File '/home/apoc/projects/ruby/rbot/lib/rbot/irc.rb', line 1566 def initialize @hostname = @version = @usermodes = @chanmodes = nil @channels = ChannelList.new @users = UserList.new reset_capabilities end |
Instance Attribute Details
- (Object) capabilities (readonly)
Returns the value of attribute capabilities
1528 1529 1530 |
# File '/home/apoc/projects/ruby/rbot/lib/rbot/irc.rb', line 1528 def capabilities @capabilities end |
- (Object) chanmodes (readonly)
Returns the value of attribute chanmodes
1527 1528 1529 |
# File '/home/apoc/projects/ruby/rbot/lib/rbot/irc.rb', line 1527 def chanmodes @chanmodes end |
- (Object) channels (readonly)
Returns the value of attribute channels
1530 1531 1532 |
# File '/home/apoc/projects/ruby/rbot/lib/rbot/irc.rb', line 1530 def channels @channels end |
- (Object) hostname (readonly)
Returns the value of attribute hostname
1527 1528 1529 |
# File '/home/apoc/projects/ruby/rbot/lib/rbot/irc.rb', line 1527 def hostname @hostname end |
- (Object) supports (readonly)
Returns the value of attribute supports
1528 1529 1530 |
# File '/home/apoc/projects/ruby/rbot/lib/rbot/irc.rb', line 1528 def supports @supports end |
- (Object) usermodes (readonly)
Returns the value of attribute usermodes
1527 1528 1529 |
# File '/home/apoc/projects/ruby/rbot/lib/rbot/irc.rb', line 1527 def usermodes @usermodes end |
- (Object) users (readonly)
Returns the value of attribute users
1530 1531 1532 |
# File '/home/apoc/projects/ruby/rbot/lib/rbot/irc.rb', line 1530 def users @users end |
- (Object) version (readonly)
Returns the value of attribute version
1527 1528 1529 |
# File '/home/apoc/projects/ruby/rbot/lib/rbot/irc.rb', line 1527 def version @version end |
Instance Method Details
- (Object) casemap
Returns the casemap of the server.
1789 1790 1791 |
# File '/home/apoc/projects/ruby/rbot/lib/rbot/irc.rb', line 1789 def casemap @supports[:casemapping] end |
- (Object) channel(str)
Returns the Channel with the given name on the server, creating it
if necessary. This is a short form for new_channel(str, nil, [],
false
)
1915 1916 1917 |
# File '/home/apoc/projects/ruby/rbot/lib/rbot/irc.rb', line 1915 def channel(str) new_channel(str,nil,[],false) end |
- (Object) channel_names
TODO Ho
1533 1534 1535 |
# File '/home/apoc/projects/ruby/rbot/lib/rbot/irc.rb', line 1533 def channel_names @channels.map { |ch| ch.downcase } end |
- (Object) clear
Clears the server
1640 1641 1642 1643 1644 |
# File '/home/apoc/projects/ruby/rbot/lib/rbot/irc.rb', line 1640 def clear reset_lists reset_capabilities @hostname = @version = @usermodes = @chanmodes = nil end |
- (Object) delete_channel(name)
Remove Channel name from the list of Channel
s
1921 1922 1923 1924 1925 |
# File '/home/apoc/projects/ruby/rbot/lib/rbot/irc.rb', line 1921 def delete_channel(name) idx = has_channel?(name) raise "Tried to remove unmanaged channel #{name}" unless idx @channels.delete_at(idx) end |
- (Object) delete_user(someuser)
Remove User someuser from the list of User
s.
someuser must be specified with the full Netmask.
1996 1997 1998 1999 2000 2001 2002 2003 2004 |
# File '/home/apoc/projects/ruby/rbot/lib/rbot/irc.rb', line 1996 def delete_user(someuser) idx = has_user?(someuser) raise "Tried to remove unmanaged user #{user}" unless idx have = self.user(someuser) @channels.each { |ch| delete_user_from_channel(have, ch) } @users.delete_at(idx) end |
- (Object) delete_user_from_channel(user, channel)
Deletes User user from Channel channel
1989 1990 1991 |
# File '/home/apoc/projects/ruby/rbot/lib/rbot/irc.rb', line 1989 def delete_user_from_channel(user, channel) channel.delete_user(user) end |
- (Object) find_users(mask)
Finds all User
s on server whose Netmask matches mask
2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 |
# File '/home/apoc/projects/ruby/rbot/lib/rbot/irc.rb', line 2014 def find_users(mask) nm = new_netmask(mask) @users.inject(UserList.new) { |list, user| if user.user == "*" or user.host == "*" list << user if user.nick.irc_downcase(casemap) =~ nm.nick.irc_downcase(casemap).to_irc_regexp else list << user if user.matches?(nm) end list } end |
- (Object) get_channel(name) Also known as: get_chan
Returns the channel with name name, if available
1824 1825 1826 1827 1828 |
# File '/home/apoc/projects/ruby/rbot/lib/rbot/irc.rb', line 1824 def get_channel(name) return nil if name.nil_or_empty? idx = has_channel?(name) channels[idx] if idx end |
- (Object) get_user(nick)
Returns the user with nick nick, if available
1936 1937 1938 1939 |
# File '/home/apoc/projects/ruby/rbot/lib/rbot/irc.rb', line 1936 def get_user(nick) idx = has_user?(nick) @users[idx] if idx end |
- (Boolean) has_channel?(name) Also known as: has_chan?
Checks if the receiver already has a channel with the given name
1816 1817 1818 1819 |
# File '/home/apoc/projects/ruby/rbot/lib/rbot/irc.rb', line 1816 def has_channel?(name) return false if name.nil_or_empty? channel_names.index(name.irc_downcase(casemap)) end |
- (Boolean) has_user?(nick)
Checks if the receiver already has a user with the given nick
1929 1930 1931 1932 |
# File '/home/apoc/projects/ruby/rbot/lib/rbot/irc.rb', line 1929 def has_user?(nick) return false if nick.nil_or_empty? user_nicks.index(nick.irc_downcase(casemap)) end |
- (Object) inspect
1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 |
# File '/home/apoc/projects/ruby/rbot/lib/rbot/irc.rb', line 1542 def inspect chans, users = [@channels, @users].map {|d| d.sort { |a, b| a.downcase <=> b.downcase }.map { |x| x.inspect } } str = self.__to_s__[0..-2] str << " @hostname=#{hostname}" str << " @channels=#{chans}" str << " @users=#{users}" str << ">" end |
- (Object) mode_for_prefix(pfx)
Convert a prefix (@, +, %, …) to the corresponding mode (o, v, h, …). See also prefix_for_mode
1621 1622 1623 1624 1625 |
# File '/home/apoc/projects/ruby/rbot/lib/rbot/irc.rb', line 1621 def mode_for_prefix(pfx) return @supports[:prefix][:modes][ @supports[:prefix][:prefixes].index(pfx.to_sym) ] end |
- (Object) new_channel(name, topic = nil, users = [], fails = true)
Create a new Channel object bound to the receiver and add it to the list of
Channel
s on the receiver, unless the channel was present
already. In this case, the default action is to raise an exception, unless
fails is set to false. An exception can also be raised if
str is nil or empty, again only if fails is set to true;
otherwise, the method just returns nil
1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 |
# File '/home/apoc/projects/ruby/rbot/lib/rbot/irc.rb', line 1838 def new_channel(name, topic=nil, users=[], fails=true) if name.nil_or_empty? raise "Tried to look for empty or nil channel name #{name.inspect}" if fails return nil end ex = get_chan(name) if ex raise "Channel #{name} already exists on server #{self}" if fails return ex else prefix = name[0,1] # Give a warning if the new Channel goes over some server limits. # # FIXME might need to raise an exception # warn "#{self} doesn't support channel prefix #{prefix}" unless @supports[:chantypes].include?(prefix) warn "#{self} doesn't support channel names this long (#{name.length} > #{@supports[:channellen]})" unless name.length <= @supports[:channellen] # Next, we check if we hit the limit for channels of type +prefix+ # if the server supports +chanlimit+ # @supports[:chanlimit].keys.each { |k| next unless k.include?(prefix) count = 0 channel_names.each { |n| count += 1 if k.include?(n[0]) } # raise IndexError, "Already joined #{count} channels with prefix #{k}" if count == @supports[:chanlimit][k] warn "Already joined #{count}/#{@supports[:chanlimit][k]} channels with prefix #{k}, we may be going over server limits" if count >= @supports[:chanlimit][k] } # So far, everything is fine. Now create the actual Channel # chan = Channel.new(name, topic, users, :server => self) # We wade through +prefix+ and +chanmodes+ to create appropriate # lists and flags for this channel @supports[:prefix][:modes].each { |mode| chan.create_mode(mode, Channel::UserMode) } if @supports[:prefix][:modes] @supports[:chanmodes].each { |k, val| if val case k when :typea val.each { |mode| chan.create_mode(mode, Channel::ModeTypeA) } when :typeb val.each { |mode| chan.create_mode(mode, Channel::ModeTypeB) } when :typec val.each { |mode| chan.create_mode(mode, Channel::ModeTypeC) } when :typed val.each { |mode| chan.create_mode(mode, Channel::ModeTypeD) } end end } @channels << chan # debug "Created channel #{chan.inspect}" return chan end end |
- (Object) new_netmask(str)
Create a new Netmask object with the appropriate casemap
2008 2009 2010 |
# File '/home/apoc/projects/ruby/rbot/lib/rbot/irc.rb', line 2008 def new_netmask(str) str.to_irc_netmask(:server => self) end |
- (Object) new_user(str, fails = true)
Create a new User object bound to the receiver and add it to the list of
User
s on the receiver, unless the User was present already. In
this case, the default action is to raise an exception, unless
fails is set to false. An exception can also be raised if
str is nil or empty, again only if fails is set to true;
otherwise, the method just returns nil
1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 |
# File '/home/apoc/projects/ruby/rbot/lib/rbot/irc.rb', line 1948 def new_user(str, fails=true) if str.nil_or_empty? raise "Tried to look for empty or nil user name #{str.inspect}" if fails return nil end tmp = str.to_irc_user(:server => self) old = get_user(tmp.nick) # debug "Tmp: #{tmp.inspect}" # debug "Old: #{old.inspect}" if old # debug "User already existed as #{old.inspect}" if tmp.known? if old.known? # debug "Both were known" # Do not raise an error: things like Freenode change the hostname after identification warning "User #{tmp.nick} has inconsistent Netmasks! #{self} knows #{old.inspect} but access was tried with #{tmp.inspect}" if old != tmp raise "User #{tmp} already exists on server #{self}" if fails end if old.fullform.downcase != tmp.fullform.downcase old.replace(tmp) # debug "Known user now #{old.inspect}" end end return old else warn "#{self} doesn't support nicknames this long (#{tmp.nick.length} > #{@supports[:nicklen]})" unless tmp.nick.length <= @supports[:nicklen] @users << tmp return @users.last end end |
- (Object) parse_isupport(line)
This method is used to parse a 005 RPL_ISUPPORT line
See the RPL_ISUPPORT draft
1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 |
# File '/home/apoc/projects/ruby/rbot/lib/rbot/irc.rb', line 1677 def parse_isupport(line) debug "Parsing ISUPPORT #{line.inspect}" ar = line.split(' ') reparse = [] ar.each { |en| prekey, val = en.split('=', 2) if prekey =~ /^-(.*)/ key = $1.downcase.to_sym val = false else key = prekey.downcase.to_sym end case key when :casemapping noval_warn(key, val) { if val == 'charset' reparse << "CASEMAPPING=(charset)" else # TODO some servers offer non-standard CASEMAPPINGs in the form # locale.charset[-options], which indicate an extended set of # allowed characters (mostly for nicks). This might be supported # with hooks for the unicode core module @supports[key] = val.to_irc_casemap end } when :chanlimit, :idchan, :maxlist, :targmax noval_warn(key, val) { groups = val.split(',') groups.each { |g| k, v = g.split(':') @supports[key][k] = v.to_i || 0 if @supports[key][k] == 0 warn "Deleting #{key} limit of 0 for #{k}" @supports[key].delete(k) end } } when :chanmodes noval_warn(key, val) { groups = val.split(',') @supports[key][:typea] = groups[0].scan(/./).map { |x| x.to_sym} @supports[key][:typeb] = groups[1].scan(/./).map { |x| x.to_sym} @supports[key][:typec] = groups[2].scan(/./).map { |x| x.to_sym} @supports[key][:typed] = groups[3].scan(/./).map { |x| x.to_sym} } when :channellen, :kicklen, :modes, :topiclen if val @supports[key] = val.to_i else @supports[key] = nil end when :chantypes @supports[key] = val # can also be nil when :excepts val ||= 'e' @supports[key] = val when :invex val ||= 'I' @supports[key] = val when :maxchannels noval_warn(key, val) { reparse << "CHANLIMIT=(chantypes):#{val} " } when :maxtargets noval_warn(key, val) { @supports[:targmax]['PRIVMSG'] = val.to_i @supports[:targmax]['NOTICE'] = val.to_i } when :network noval_warn(key, val) { @supports[key] = val } when :nicklen noval_warn(key, val) { @supports[key] = val.to_i } when :prefix if val val.scan(/\((.*)\)(.*)/) { |m, p| @supports[key][:modes] = m.scan(/./).map { |x| x.to_sym} @supports[key][:prefixes] = p.scan(/./).map { |x| x.to_sym} } else @supports[key][:modes] = nil @supports[key][:prefixes] = nil end when :safelist val_warn(key, val) { @supports[key] = val.nil? ? true : val } when :statusmsg noval_warn(key, val) { @supports[key] = val.scan(/./) } when :std noval_warn(key, val) { @supports[key] = val.split(',') } else @supports[key] = val.nil? ? true : val end } unless reparse.empty? reparse_str = reparse.join(" ") reparse_str.gsub!("(chantypes)",@supports[:chantypes]) reparse_str.gsub!("(charset)",@supports[:charset] || 'rfc1459') parse_isupport(reparse_str) end end |
- (Object) parse_my_info(line)
This method is used to parse a 004 RPL_MY_INFO line
1648 1649 1650 1651 1652 1653 1654 |
# File '/home/apoc/projects/ruby/rbot/lib/rbot/irc.rb', line 1648 def parse_my_info(line) ar = line.split(' ') @hostname = ar[0] @version = ar[1] @usermodes = ar[2] @chanmodes = ar[3] end |
- (Object) prefix_for_mode(mode)
Convert a mode (o, v, h, …) to the corresponding prefix (@, +, %, …). See also mode_for_prefix
1613 1614 1615 1616 1617 |
# File '/home/apoc/projects/ruby/rbot/lib/rbot/irc.rb', line 1613 def prefix_for_mode(mode) return @supports[:prefix][:prefixes][ @supports[:prefix][:modes].index(mode.to_sym) ] end |
- (Object) reset_capabilities
Resets the server capabilities
1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 |
# File '/home/apoc/projects/ruby/rbot/lib/rbot/irc.rb', line 1578 def reset_capabilities @supports = { :casemapping => 'rfc1459'.to_irc_casemap, :chanlimit => {}, :chanmodes => { :typea => nil, # Type A: address lists :typeb => nil, # Type B: needs a parameter :typec => nil, # Type C: needs a parameter when set :typed => nil # Type D: must not have a parameter }, :channellen => 50, :chantypes => "#&!+", :excepts => nil, :idchan => {}, :invex => nil, :kicklen => nil, :maxlist => {}, :modes => 3, :network => nil, :nicklen => 9, :prefix => { :modes => [:o, :v], :prefixes => [:@", :+] }, :safelist => nil, :statusmsg => nil, :std => nil, :targmax => {}, :topiclen => nil } @capabilities = {} end |
- (Object) reset_lists
Resets the Channel and User list
1629 1630 1631 1632 1633 1634 1635 1636 |
# File '/home/apoc/projects/ruby/rbot/lib/rbot/irc.rb', line 1629 def reset_lists @users.reverse_each { |u| delete_user(u) } @channels.reverse_each { |u| delete_channel(u) } end |
- (Object) to_s
1558 1559 1560 |
# File '/home/apoc/projects/ruby/rbot/lib/rbot/irc.rb', line 1558 def to_s hostname.nil? ? "<no hostname>" : hostname end |
- (Object) user(str)
Returns the User with the given Netmask on the server, creating it if
necessary. This is a short form for new_user(str,
false
)
1983 1984 1985 |
# File '/home/apoc/projects/ruby/rbot/lib/rbot/irc.rb', line 1983 def user(str) new_user(str, false) end |
- (Object) user_nicks
TODO Ho
1538 1539 1540 |
# File '/home/apoc/projects/ruby/rbot/lib/rbot/irc.rb', line 1538 def user_nicks @users.map { |u| u.downcase } end |
- (Object) user_or_channel(name)
Returns the actual User or Channel object matching name
1806 1807 1808 1809 1810 1811 1812 |
# File '/home/apoc/projects/ruby/rbot/lib/rbot/irc.rb', line 1806 def user_or_channel(name) if supports[:chantypes].include?(name[0]) return channel(name) else return user(name) end end |
- (Boolean) user_or_channel?(name)
Returns User or Channel depending on what name can be a name of
1796 1797 1798 1799 1800 1801 1802 |
# File '/home/apoc/projects/ruby/rbot/lib/rbot/irc.rb', line 1796 def user_or_channel?(name) if supports[:chantypes].include?(name[0]) return Channel else return User end end |