Class: IRC::Client
- Inherits:
-
Object
- Object
- IRC::Client
- Includes:
- Loggable, Rhuidean
- Defined in:
- lib/rhuidean/client.rb,
lib/rhuidean/methods.rb
Overview
These methods are shortcuts for sending data to the IRC server. You can use `raw` to do any of them, or even add a string directly to `@sendq` if you really want. I'm sure I haven't thought of everything here.
Direct Known Subclasses
Defined Under Namespace
Classes: Error
Constant Summary
- IRC_RE =
Note that this doesn't match every IRC message, just the ones we care about. It also doesn't match every IRC message in the way we want. We get what we need. The rest is ignored.
Here's a compact version if you need it:
^(?:\:([^\s]+)\s)?(\w+)\s(?:([^\s\:]+)\s)?(?:\:?(.*))?$ / ^ # beginning of string (?: # non-capturing group \: # if we have a ':' then we have an origin ([^\s]+) # get the origin without the ':' \s # space after the origin )? # close non-capturing group (\w+) # must have a command \s # and a space after it (?: # non-capturing group ([^\s\:]+) # a target for the command \s # and a space after it )? # close non-capturing group (?: # non-capturing group \:? # if we have a ':' then we have freeform text (.*) # get the rest as one string without the ':' )? # close non-capturing group $ # end of string /x
Constants included from Rhuidean
Rhuidean::VERSION, Rhuidean::V_MAJOR, Rhuidean::V_MINOR, Rhuidean::V_PATCH
Instance Attribute Summary (collapse)
-
- (Object) bind_to
instance attributes.
-
- (Object) nickname
instance attributes.
-
- (Object) password
instance attributes.
-
- (Object) port
instance attributes.
-
- (Object) realname
instance attributes.
-
- (Object) server
instance attributes.
-
- (Object) socket
readonly
Our TCPSocket.
-
- (Object) thread
instance attributes.
-
- (Object) username
instance attributes.
Instance Method Summary (collapse)
-
- (Object) connect
Creates and connects our socket.
-
- (Boolean) connected?
Are we connected?
returns
true or false.
-
- (Object) ctcp(to, type, params = nil)
Sends a CTCP.
-
- (Object) ctcp_reply(to, type, params = '')
Sends a CTCP reply.
-
- (Boolean) dead?
Is the socket dead?
returns
true or false.
-
- (Object) exit(from = 'exit')
Forces the Client's Thread to die.
-
- (Client) initialize {|_self| ... }
constructor
Creates a new IRC::Client object.
-
- (Object) invite(target, channel)
Sends an IRC INVITE command.
-
- (Object) io_loop
Schedules input/output and runs the EventQueue.
-
- (Object) join(channel, key = '')
Sends an IRC JOIN command.
-
- (Object) kick(channel, target, reason = '')
Sends an IRC KICK command.
-
- (Object) mode(target, mode = '')
Sends an IRC MODE command.
-
- (Object) nick(nick)
Sends an IRC NICK command.
-
- (Object) notice(to, message)
Sends an IRC NOTICE command.
-
- (Object) on(event, &block)
Registers Event handlers with our EventQueue.
-
- (Object) part(channel, message = '')
Sends an IRC PART command.
-
- (Object) pass(password)
Sends an IRC PASS command.
-
- (Object) privmsg(to, message)
Sends an IRC PRIVMSG command.
-
- (Object) quit(message = '')
Send an IRC QUIT command.
-
- (Object) raw(message)
Sends text directly to the server.
-
- (Object) to_s
Represent ourselves in a string.
-
- (Object) topic(target, new = '')
Sends an IRC TOPIC command.
-
- (Object) umode(mode)
Sends an IRC MODE command.
-
- (Object) user(username, server, host, realname)
Sends an IRC USER command.
Methods included from Loggable
Constructor Details
- (Client) initialize {|_self| ... }
Creates a new IRC::Client object. If there is a block given, passes itself to the block for pretty attribute setting.
<tt>client = IRC::Client.new do |c|
c.server = 'irc.malkier.net'
c.port = 6667
c.password = 'partypants'
c.nickname = 'rakaur'
c.username = 'rakaur'
c.realname = 'watching the weather change'
c.bind_to = '10.0.1.20'
c.logger = Logger.new($stderr)
c.log_level = :debug
end
client.thread = Thread.new { client.io_loop } clients.each { |client| client.thread.join }
- ...
-
client.quit("IRC quit message!") client.exit
returns
self
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
# File 'lib/rhuidean/client.rb', line 58 def initialize # Is our socket dead? @dead = false @connected = false # Received data waiting to be parsed. @recvq = [] # Data waiting to be sent. @sendq = [] # Our event queue. @eventq = EventQueue.new # Local IP to bind to @bind_to = nil # Password to login to the server @password = nil # Our Logger object. @logger = Logger.new($stderr) self.log_level = :info # If we have a block let it set up our instance attributes. yield(self) if block_given? # Core events which are needed to work at all. on(:read_ready) { read } on(:write_ready) { write } on(:recvq_ready) { parse } on(:dead) { self.dead = true } on(:exit) do |from| log(:fatal, "exiting via #{from}...") Thread.exit end on(:PING) { |m| raw("PONG :#{m.target}") } # Set up event handlers. These track some state and such, and can # be overridden for other functionality in any child classes. set_default_handlers # Special method for default CTCP replies # I use this so they don't get wiped out when someone overrides # the default handlers, but also so that they CAN be wiped out. set_ctcp_handlers self end |
Instance Attribute Details
- (Object) bind_to
instance attributes
23 24 25 |
# File 'lib/rhuidean/client.rb', line 23 def bind_to @bind_to end |
- (Object) nickname
instance attributes
23 24 25 |
# File 'lib/rhuidean/client.rb', line 23 def nickname @nickname end |
- (Object) password
instance attributes
23 24 25 |
# File 'lib/rhuidean/client.rb', line 23 def password @password end |
- (Object) port
instance attributes
23 24 25 |
# File 'lib/rhuidean/client.rb', line 23 def port @port end |
- (Object) realname
instance attributes
23 24 25 |
# File 'lib/rhuidean/client.rb', line 23 def realname @realname end |
- (Object) server
instance attributes
23 24 25 |
# File 'lib/rhuidean/client.rb', line 23 def server @server end |
- (Object) socket (readonly)
Our TCPSocket.
27 28 29 |
# File 'lib/rhuidean/client.rb', line 27 def socket @socket end |
- (Object) thread
instance attributes
23 24 25 |
# File 'lib/rhuidean/client.rb', line 23 def thread @thread end |
- (Object) username
instance attributes
23 24 25 |
# File 'lib/rhuidean/client.rb', line 23 def username @username end |
Instance Method Details
- (Object) connect
Creates and connects our socket.
returns |
self |
398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 |
# File 'lib/rhuidean/client.rb', line 398 def connect verify_attributes log(:info, "connecting to #@server:#@port") begin @socket = TCPSocket.new(@server, @port, @bind_to) rescue Exception => err @eventq.post(:dead) end @dead = false @connected = true pass(@password) if @password nick(@nickname) user(@username, @server, @server, @realname) end |
- (Boolean) connected?
Are we connected?
returns |
true or false |
389 390 391 |
# File 'lib/rhuidean/client.rb', line 389 def connected? @connected end |
- (Object) ctcp(to, type, params = nil)
Sends a CTCP
47 48 49 50 51 52 53 |
# File 'lib/rhuidean/methods.rb', line 47 def ctcp(to, type, params = nil) if params @sendq << "PRIVMSG #{to} :\1#{type} #{params}\1" else @sendq << "PRIVMSG #{to} :\1#{type}\1" end end |
- (Object) ctcp_reply(to, type, params = '')
Sends a CTCP reply
61 62 63 |
# File 'lib/rhuidean/methods.rb', line 61 def ctcp_reply(to, type, params = '') @sendq << "NOTICE #{to} :\1#{type} #{params}\1" end |
- (Boolean) dead?
Is the socket dead?
returns |
true or false |
380 381 382 |
# File 'lib/rhuidean/client.rb', line 380 def dead? @dead end |
- (Object) exit(from = 'exit')
Forces the Client's Thread to die. If it's the main thread, the application goes with it.
returns |
nope! |
432 433 434 435 |
# File 'lib/rhuidean/client.rb', line 432 def exit(from = 'exit') @eventq.post(:exit, from) @eventq.run end |
- (Object) invite(target, channel)
Sends an IRC INVITE command.
96 97 98 |
# File 'lib/rhuidean/methods.rb', line 96 def invite(target, channel) @senq << "INVITE #{target} #{channel}" end |
- (Object) io_loop
Schedules input/output and runs the EventQueue.
returns |
never, thread dies on :exit |
340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 |
# File 'lib/rhuidean/client.rb', line 340 def io_loop loop do if dead? sleep(30) connect next end connect unless connected? # Run the event loop. These events will add IO, and possibly other # events, so we keep running until it's empty. @eventq.run while @eventq.needs_ran? next if dead? writefd = [@socket] unless @sendq.empty? # Ruby's threads suck. In theory, the timers should # manage themselves in separate threads. Unfortunately, # Ruby has a global lock and the scheduler isn't great, so # this tells select() to timeout when the next timer needs to run. timeout = (Timer.next_time - Time.now.to_f).round timeout = 1 if timeout == 0 # Don't want 0, that's forever timeout = 60 if timeout < 0 # Less than zero means no timers ret = IO.select([@socket], writefd, [], timeout) next unless ret @eventq.post(:read_ready) unless ret[0].empty? @eventq.post(:write_ready) unless ret[1].empty? end end |
- (Object) join(channel, key = '')
Sends an IRC JOIN command.
66 67 68 |
# File 'lib/rhuidean/methods.rb', line 66 def join(channel, key = '') @sendq << "JOIN #{channel} #{key}" end |
- (Object) kick(channel, target, reason = '')
Sends an IRC KICK command.
76 77 78 |
# File 'lib/rhuidean/methods.rb', line 76 def kick(channel, target, reason = '') @sendq << "KICK #{channel} #{target} :#{reason}" end |
- (Object) mode(target, mode = '')
Sends an IRC MODE command.
91 92 93 |
# File 'lib/rhuidean/methods.rb', line 91 def mode(target, mode = '') @sendq << "MODE #{target} #{mode}" end |
- (Object) nick(nick)
Sends an IRC NICK command.
27 28 29 |
# File 'lib/rhuidean/methods.rb', line 27 def nick(nick) @sendq << "NICK #{nick}" end |
- (Object) notice(to, message)
Sends an IRC NOTICE command.
56 57 58 |
# File 'lib/rhuidean/methods.rb', line 56 def notice(to, ) @sendq << "NOTICE #{to} :#{}" end |
- (Object) on(event, &block)
Registers Event handlers with our EventQueue.
<tt>c.on(:PRIVMSG) do |m|
next if m.params.empty?
if m.params =~ /\.die/ and m.origin == my_master
c.quit(params)
c.exit
end</tt>
event |
name of the event as a Symbol |
block |
block to call when Event is posted |
returns |
self |
329 330 331 332 333 |
# File 'lib/rhuidean/client.rb', line 329 def on(event, &block) @eventq.handle(event, &block) self end |
- (Object) part(channel, message = '')
Sends an IRC PART command.
71 72 73 |
# File 'lib/rhuidean/methods.rb', line 71 def part(channel, = '') @sendq << "PART #{channel} :#{}" end |
- (Object) pass(password)
Sends an IRC PASS command.
37 38 39 |
# File 'lib/rhuidean/methods.rb', line 37 def pass(password) @sendq << "PASS #{password}" end |
- (Object) privmsg(to, message)
Sends an IRC PRIVMSG command.
42 43 44 |
# File 'lib/rhuidean/methods.rb', line 42 def privmsg(to, ) @sendq << "PRIVMSG #{to} :#{}" end |
- (Object) quit(message = '')
Send an IRC QUIT command.
101 102 103 |
# File 'lib/rhuidean/methods.rb', line 101 def quit( = '') @sendq << "QUIT :#{}" end |
- (Object) raw(message)
Sends text directly to the server.
22 23 24 |
# File 'lib/rhuidean/methods.rb', line 22 def raw() @sendq << end |
- (Object) to_s
Represent ourselves in a string.
returns |
our nickname and object ID |
422 423 424 |
# File 'lib/rhuidean/client.rb', line 422 def to_s "#{@nickname}:#{self.object_id}" end |
- (Object) topic(target, new = '')
Sends an IRC TOPIC command.
81 82 83 |
# File 'lib/rhuidean/methods.rb', line 81 def topic(target, new = '') @sendq << "TOPIC #{target} :#{new}" end |
- (Object) umode(mode)
Sends an IRC MODE command.
86 87 88 |
# File 'lib/rhuidean/methods.rb', line 86 def umode(mode) @sendq << "MODE #@nickname #{mode}" end |
- (Object) user(username, server, host, realname)
Sends an IRC USER command.
32 33 34 |
# File 'lib/rhuidean/methods.rb', line 32 def user(username, server, host, realname) @sendq << "USER #{username} #{server} #{host} :#{realname}" end |