From 205ab1dbb401ea9b9981801ff9d0f8f6ef034241 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hinrik=20=C3=96rn=20Sigur=C3=B0sson?= Date: Sun, 22 May 2011 16:15:21 +0000 Subject: [PATCH] Rename a Pod heading --- README.pod | 1576 ++++++++++++++++++++++++++++++++++++++ lib/POE/Component/IRC.pm | 2 +- 2 files changed, 1577 insertions(+), 1 deletion(-) diff --git a/README.pod b/README.pod index e69de29b..7f931ff7 100644 --- a/README.pod +++ b/README.pod @@ -0,0 +1,1576 @@ +=encoding utf8 + +=head1 NAME + +POE::Component::IRC - A fully event-driven IRC client module + +=head1 SYNOPSIS + + # A simple Rot13 'encryption' bot + + use strict; + use warnings; + use POE qw(Component::IRC); + + my $nickname = 'Flibble' . $$; + my $ircname = 'Flibble the Sailor Bot'; + my $server = 'irc.perl.org'; + + my @channels = ('#Blah', '#Foo', '#Bar'); + + # We create a new PoCo-IRC object + my $irc = POE::Component::IRC->spawn( + nick => $nickname, + ircname => $ircname, + server => $server, + ) or die "Oh noooo! $!"; + + POE::Session->create( + package_states => [ + main => [ qw(_default _start irc_001 irc_public) ], + ], + heap => { irc => $irc }, + ); + + $poe_kernel->run(); + + sub _start { + my $heap = $_[HEAP]; + + # retrieve our component's object from the heap where we stashed it + my $irc = $heap->{irc}; + + $irc->yield( register => 'all' ); + $irc->yield( connect => { } ); + return; + } + + sub irc_001 { + my $sender = $_[SENDER]; + + # Since this is an irc_* event, we can get the component's object by + # accessing the heap of the sender. Then we register and connect to the + # specified server. + my $irc = $sender->get_heap(); + + print "Connected to ", $irc->server_name(), "\n"; + + # we join our channels + $irc->yield( join => $_ ) for @channels; + return; + } + + sub irc_public { + my ($sender, $who, $where, $what) = @_[SENDER, ARG0 .. ARG2]; + my $nick = ( split /!/, $who )[0]; + my $channel = $where->[0]; + + if ( my ($rot13) = $what =~ /^rot13 (.+)/ ) { + $rot13 =~ tr[a-zA-Z][n-za-mN-ZA-M]; + $irc->yield( privmsg => $channel => "$nick: $rot13" ); + } + return; + } + + # We registered for all events, this will produce some debug info. + sub _default { + my ($event, $args) = @_[ARG0 .. $#_]; + my @output = ( "$event: " ); + + for my $arg (@$args) { + if ( ref $arg eq 'ARRAY' ) { + push( @output, '[' . join(', ', @$arg ) . ']' ); + } + else { + push ( @output, "'$arg'" ); + } + } + print join ' ', @output, "\n"; + return; + } + +=head1 DESCRIPTION + +POE::Component::IRC is a POE component (who'd have guessed?) which +acts as an easily controllable IRC client for your other POE +components and sessions. You create an IRC component and tell it what +events your session cares about and where to connect to, and it sends +back interesting IRC events when they happen. You make the client do +things by sending it events. That's all there is to it. Cool, no? + +[Note that using this module requires some familiarity with the +details of the IRC protocol. I'd advise you to read up on the gory +details of RFC 1459 (L) before you +get started. Keep the list of server numeric codes handy while you +program. Needless to say, you'll also need a good working knowledge of +POE, or this document will be of very little use to you.] + +The POE::Component::IRC distribution has a F folder with a collection of +salient documentation including the pertinent RFCs. + +POE::Component::IRC consists of a POE::Session that manages the IRC connection +and dispatches C prefixed events to interested sessions and +an object that can be used to access additional information using methods. + +Sessions register their interest in receiving C events by sending +L|/register> to the component. One would usually do this in +your C<_start> handler. Your session will continue to receive events until +you L|/unregister>. The component will continue to stay +around until you tell it not to with L|/shutdown>. + +The L demonstrates a fairly basic bot. + +See L for more +examples. + +=head2 Useful subclasses + +Included with POE::Component::IRC are a number of useful subclasses. As they +are subclasses they support all the methods, etc. documented here and have +additional methods and quirks which are documented separately: + +=over 4 + +=item * L + +POE::Component::IRC::State provides all the functionality of POE::Component::IRC +but also tracks IRC state entities such as nicks and channels. + +=item * L + +POE::Component::IRC::Qnet is POE::Component::IRC tweaked for use on Quakenet IRC +network. + +=item * L + +POE::Component::IRC::Qnet::State is a tweaked version of POE::Component::IRC::State +for use on the Quakenet IRC network. + +=back + +=head2 The Plugin system + +As of 3.7, PoCo-IRC sports a plugin system. The documentation for it can be +read by looking at L. +That is not a subclass, just a placeholder for documentation! + +A number of useful plugins have made their way into the core distribution: + +=over 4 + +=item * L + +Provides DCC support. Loaded by default. + +=item * L + +Keeps you on your favorite channels throughout reconnects and even kicks. + +=item * L + +Glues an irc bot to an IRC network, i.e. deals with maintaining ircd connections. + +=item * L + +Under normal circumstances irc bots do not normal the msgs and public msgs that +they generate themselves. This plugin enables you to handle those events. + +=item * L + +Generates C / C / C +events whenever your bot's name comes up in channel discussion. + +=item * L + +Provides an easy way to handle commands issued to your bot. + +=item * L + +See inside the component. See what events are being sent. Generate irc commands +manually. A TCP based console. + +=item * L + +Follow the tail of an ever-growing file. + +=item * L + +Log public and private messages to disk. + +=item * L + +Identify with NickServ when needed. + +=item *L + +A lightweight IRC proxy/bouncer. + +=item * L + +Automagically generates replies to ctcp version, time and userinfo queries. + +=item * L + +An experimental Plugin Manager plugin. + +=item * L + +Automagically deals with your nickname being in use and reclaiming it. + +=item * L + +Cycles (parts and rejoins) channels if they become empty and opless, in order +to gain ops. + +=back + +=head1 CONSTRUCTORS + +Both constructors return an object. The object is also available within 'irc_' +event handlers by using C<< $_[SENDER]->get_heap() >>. See also +L|/register> and L|/irc_registered>. + +=head2 C + +Takes a number of arguments, all of which are optional. All the options +below may be supplied to the L|/connect> input event as well, +except for B<'alias'>, B<'options'>, B<'NoDNS'>, B<'debug'>, and +B<'plugin_debug'>. + +=over 4 + +=item * B<'alias'>, a name (kernel alias) that this instance will be known +by; + +=item * B<'options'>, a hashref containing L +options; + +=item * B<'Server'>, the server name; + +=item * B<'Port'>, the remote port number; + +=item * B<'Password'>, an optional password for restricted servers; + +=item * B<'Nick'>, your client's IRC nickname; + +=item * B<'Username'>, your client's username; + +=item * B<'Ircname'>, some cute comment or something. + +=item * B<'Bitmode'>, an integer representing your initial user modes set +in the USER command. See RFC 2812. If you do not set this, C<8> (+i) will +be used. + +=item * B<'UseSSL'>, set to some true value if you want to connect using +SSL. + +=item * B<'Raw'>, set to some true value to enable the component to send +L|/irc_raw> and L|/irc_raw_out> events. + +=item * B<'LocalAddr'>, which local IP address on a multihomed box to +connect as; + +=item * B<'LocalPort'>, the local TCP port to open your socket on; + +=item * B<'NoDNS'>, set this to 1 to disable DNS lookups using +PoCo-Client-DNS. (See note below). + +=item * B<'Flood'>, when true, it disables the component's flood +protection algorithms, allowing it to send messages to an IRC server at +full speed. Disconnects and k-lines are some common side effects of +flooding IRC servers, so care should be used when enabling this option. +Default is false. + +Two new attributes are B<'Proxy'> and B<'ProxyPort'> for sending your +=item * B<'Proxy'>, IP address or server name of a proxy server to use. + +=item * B<'ProxyPort'>, which tcp port on the proxy to connect to. + +=item * B<'NATAddr'>, what other clients see as your IP address. + +=item * B<'DCCPorts'>, an arrayref containing tcp ports that can be used +for DCC sends. + +=item * B<'Resolver'>, provide a L object for the component to use. + +=item * B<'msg_length'>, the maximum length of IRC messages, in bytes. +Default is 450. The IRC component shortens all messages longer than this +value minus the length of your current nickname. IRC only allows raw +protocol lines messages that are 512 bytes or shorter, including the +trailing "\r\n". This is most relevant to long PRIVMSGs. The IRC component +can't be sure how long your user@host mask will be every time you send a +message, considering that most networks mangle the 'user' part and some +even replace the whole string (think FreeNode cloaks). If you have an +unusually long user@host mask you might want to decrease this value if +you're prone to sending long messages. Conversely, if you have an +unusually short one, you can increase this value if you want to be able to +send as long a message as possible. Be careful though, increase it too +much and the IRC server might disconnect you with a "Request too long" +message when you try to send a message that's too long. + +=item * B<'debug'>, if set to a true value causes the IRC component to +print every message sent to and from the server, as well as print some +warnings when it receives malformed messages. This option will be enabled +if the C environment variable is set to a true value. + +=item * B<'plugin_debug'>, set to some true value to print plugin debug +info, default 0. Plugins are processed inside an eval. When you enable +this option, you will be notified when (and why) a plugin raises an +exception. This option will be enabled if the C environment +variable is set to a true value. + +=item * B<'socks_proxy'>, specify a SOCKS4/SOCKS4a proxy to use. + +=item * B<'socks_port'>, the SOCKS port to use, defaults to 1080 if not +specified. + +=item * B<'socks_id'>, specify a SOCKS user_id. Default is none. + +=item * B<'useipv6'>, enable the use of IPv6 for connections. + +=back + +C will supply reasonable defaults for any of these attributes +which are missing, so don't feel obliged to write them all out. + +If the component finds that L +is installed it will use that to resolve the server name passed. Disable +this behaviour if you like, by passing: C<< NoDNS => 1 >>. + +IRC traffic through a proxy server. B<'Proxy'>'s value should be the IP +address or server name of the proxy. B<'ProxyPort'>'s value should be the +port on the proxy to connect to. L|/connect> will default +to using the I IRC server's port if you provide a proxy but omit +the proxy's port. These are for HTTP Proxies. See B<'socks_proxy'> for +SOCKS4 and SOCKS4a support. + +For those people who run bots behind firewalls and/or Network Address +Translation there are two additional attributes for DCC. B<'DCCPorts'>, +is an arrayref of ports to use when initiating DCC connections. +B<'NATAddr'>, is the NAT'ed IP address that your bot is hidden behind, +this is sent whenever you do DCC. + +SSL support requires L, as +well as an IRC server that supports SSL connections. If you're missing +POE::Component::SSLify, specifying B<'UseSSL'> will do nothing. The +default is to not try to use SSL. + +B<'Resolver'>, requires a L +object. Useful when spawning multiple poco-irc sessions, saves the +overhead of multiple dns sessions. + +B<'NoDNS'> has different results depending on whether it is set with +L|/spawn> or L|/connect>. Setting it with +C, disables the creation of the POE::Component::Client::DNS +completely. Setting it with L|/connect> on the other hand +allows the PoCo-Client-DNS session to be spawned, but will disable +any dns lookups using it. + +SOCKS4 proxy support is provided by B<'socks_proxy'>, B<'socks_port'> and +B<'socks_id'> parameters. If something goes wrong with the SOCKS connection +you should get a warning on STDERR. This is fairly experimental currently. + +IPv6 support is available for connecting to IPv6 enabled ircds (it won't +work for DCC though). To enable it, specify B<'useipv6'>. Perl >=5.14 or +L (for older Perls) is required. If you that and +L installed and +specify a hostname that resolves to an IPv6 address then IPv6 will be used. +If you specify an ipv6 B<'localaddr'> then IPv6 will be used. + +=head2 C + +This method is deprecated. See the L|/spawn> method instead. +The first argument should be a name (kernel alias) which this new +connection will be known by. Optionally takes more arguments (see +L|/spawn> as name/value pairs. Returns a POE::Component::IRC +object. :) + +B Use of this method will generate a warning. There are currently no +plans to make it die() >;] + +=head1 METHODS + +=head2 Information + +=head3 C + +Takes no arguments. Returns the server host we are currently connected to +(or trying to connect to). + +=head3 C + +Takes no arguments. Returns the server port we are currently connected to +(or trying to connect to). + +=head3 C + +Takes no arguments. Returns the name of the IRC server that the component +is currently connected to. + +=head3 C + +Takes no arguments. Returns the IRC server version. + +=head3 C + +Takes no arguments. Returns a scalar containing the current nickname that the +bot is using. + +=head3 C + +Takes no arguments. Returns the IP address being used. + +=head3 C + +The component provides anti-flood throttling. This method takes no arguments +and returns a scalar representing the number of messages that are queued up +waiting for dispatch to the irc server. + +=head3 C + +Takes no arguments. Returns true or false depending on whether the IRC +component is logged into an IRC network. + +=head3 C + +Takes no arguments. Returns true or false depending on whether the component's +socket is currently connected. + +=head3 C + +Takes no arguments. Terminates the socket connection disgracefully >;o] + +=head3 C + +Takes one argument, a server capability to query. Returns C on failure +or a value representing the applicable capability. A full list of capabilities +is available at L. + +=head3 C + +Takes no arguments, returns a list of the available server capabilities keys, +which can be used with L|/isupport>. + +=head3 C + +Returns a reference to the L +object that is internally created by the component. + +=head2 Events + +=head3 C + +I> + +Takes no arguments. Returns the ID of the component's session. Ideal for posting +events to the component. + + $kernel->post($irc->session_id() => 'mode' => $channel => '+o' => $dude); + +=head3 C + +I> + +Takes no arguments. Returns the session alias that has been set through +L|/spawn>'s B<'alias'> argument. + +=head3 C + +With no arguments, returns true or false depending on whether +L|/irc_raw> and L|/irc_raw_out> events are being generated +or not. Provide a true or false argument to enable or disable this feature +accordingly. + +=head3 C + +I> + +This method provides an alternative object based means of posting events to the +component. First argument is the event to post, following arguments are sent as +arguments to the resultant post. + + $irc->yield(mode => $channel => '+o' => $dude); + +=head3 C + +I> + +This method provides an alternative object based means of calling events to the +component. First argument is the event to call, following arguments are sent as +arguments to the resultant +call. + + $irc->call(mode => $channel => '+o' => $dude); + +=head3 C + +I> + +This method provides a way of posting delayed events to the component. The +first argument is an arrayref consisting of the delayed command to post and +any command arguments. The second argument is the time in seconds that one +wishes to delay the command being posted. + + my $alarm_id = $irc->delay( [ mode => $channel => '+o' => $dude ], 60 ); + +Returns an alarm ID that can be used with L|/delay_remove> +to cancel the delayed event. This will be undefined if something went wrong. + +=head3 C + +I> + +This method removes a previously scheduled delayed event from the component. +Takes one argument, the C that was returned by a +L|/delay> method call. + + my $arrayref = $irc->delay_remove( $alarm_id ); + +Returns an arrayref that was originally requested to be delayed. + +=head3 C + +I> + +Sends an event through the component's event handling system. These will get +processed by plugins then by registered sessions. First argument is the event +name, followed by any parameters for that event. + +=head3 C + +I> + +This sends an event right after the one that's currently being processed. +Useful if you want to generate some event which is directly related to +another event so you want them to appear together. This method can only be +called when POE::Component::IRC is processing an event, e.g. from one of your +event handlers. Takes the same arguments as L|/send_event>. + +=head3 C + +I> + +This will send an event to be processed immediately. This means that if an +event is currently being processed and there are plugins or sessions which +will receive it after you do, then an event sent with C will +be received by those plugins/sessions I the current event. Takes the +same arguments as L|/send_event>. + +=head2 Plugins + +=head3 C + +I> + +Returns the L +object. + +=head3 C + +I> + +Accepts two arguments: + + The alias for the plugin + The actual plugin object + Any number of extra arguments + +The alias is there for the user to refer to it, as it is possible to have +multiple plugins of the same kind active in one Object::Pluggable object. + +This method goes through the pipeline's C method, which will call +C<< $plugin->plugin_register($pluggable, @args) >>. + +Returns the number of plugins now in the pipeline if plugin was initialized, +C/an empty list if not. + +=head3 C + +I> + +Accepts the following arguments: + + The alias for the plugin or the plugin object itself + Any number of extra arguments + +This method goes through the pipeline's C method, which will call +C<< $plugin->plugin_unregister($pluggable, @args) >>. + +Returns the plugin object if the plugin was removed, C/an empty list +if not. + +=head3 C + +I> + +Accepts the following arguments: + + The alias for the plugin + +This method goes through the pipeline's C method. + +Returns the plugin object if it was found, C/an empty list if not. + +=head3 C + +I> + +Takes no arguments. + +Returns a hashref of plugin objects, keyed on alias, or an empty list if +there are no plugins loaded. + +=head3 C + +I> + +Takes no arguments. + +Returns an arrayref of plugin objects, in the order which they are +encountered in the pipeline. + +=head3 C + +I> + +Accepts the following arguments: + + The plugin object + The type of the hook (the hook types are specified with _pluggable_init()'s 'types') + The event name[s] to watch + +The event names can be as many as possible, or an arrayref. They correspond +to the prefixed events and naturally, arbitrary events too. + +You do not need to supply events with the prefix in front of them, just the +names. + +It is possible to register for all events by specifying 'all' as an event. + +Returns 1 if everything checked out fine, C/an empty list if something +is seriously wrong. + +=head3 C + +I> + +Accepts the following arguments: + + The plugin object + The type of the hook (the hook types are specified with _pluggable_init()'s 'types') + The event name[s] to unwatch + +The event names can be as many as possible, or an arrayref. They correspond +to the prefixed events and naturally, arbitrary events too. + +You do not need to supply events with the prefix in front of them, just the +names. + +It is possible to register for all events by specifying 'all' as an event. + +Returns 1 if all the event name[s] was unregistered, undef if some was not +found. + +=head1 INPUT EVENTS + +How to talk to your new IRC component... here's the events we'll accept. +These are events that are posted to the component, either via +C<< $poe_kernel->post() >> or via the object method L|/yield>. + +So the following would be functionally equivalent: + + sub irc_001 { + my ($kernel,$sender) = @_[KERNEL,SENDER]; + my $irc = $sender->get_heap(); # obtain the poco's object + + $irc->yield( privmsg => 'foo' => 'Howdy!' ); + $kernel->post( $sender => privmsg => 'foo' => 'Howdy!' ); + $kernel->post( $irc->session_id() => privmsg => 'foo' => 'Howdy!' ); + $kernel->post( $irc->session_alias() => privmsg => 'foo' => 'Howdy!' ); + + return; + } + +=head2 Important Commands + +=head3 C + +I> + +Takes N arguments: a list of event names that your session wants to +listen for, minus the C prefix. So, for instance, if you just +want a bot that keeps track of which people are on a channel, you'll +need to listen for JOINs, PARTs, QUITs, and KICKs to people on the +channel you're in. You'd tell POE::Component::IRC that you want those +events by saying this: + + $kernel->post('my client', 'register', qw(join part quit kick)); + +Then, whenever people enter or leave a channel your bot is on (forcibly +or not), your session will receive events with names like +L|/irc_join>, L|/irc_kick>, etc., +which you can use to update a list of people on the channel. + +Registering for B<'all'> will cause it to send all IRC-related events to +you; this is the easiest way to handle it. See the test script for an +example. + +Registering will generate an L|/irc_registered> +event that your session can trap. C is the components object. Useful +if you want to bolt PoCo-IRC's new features such as Plugins into a bot +coded to the older deprecated API. If you are using the new API, ignore this :) + +Registering with multiple component sessions can be tricky, especially if +one wants to marry up sessions/objects, etc. Check the L +section for an alternative method of registering with multiple poco-ircs. + +Starting with version 4.96, if you spawn the component from inside another POE +session, the component will automatically register that session as wanting +B<'all'> irc events. That session will receive an +L|/irc_registered> event indicating that the component +is up and ready to go. + +=head3 C + +I> + +Takes N arguments: a list of event names which you I want to +receive. If you've previously done a L|/register> +for a particular event which you no longer care about, this event will +tell the IRC connection to stop sending them to you. (If you haven't, it just +ignores you. No big deal.) + +If you have registered with 'all', attempting to unregister individual +events such as 'mode', etc. will not work. This is a 'feature'. + +=head3 C + +Takes one argument: a hash reference of attributes for the new connection, +see L|/spawn> for details. This event tells the IRC client to +connect to a new/different server. If it has a connection already open, it'll +close it gracefully before reconnecting. + +=head3 C and C + +Sends a CTCP query or response to the nick(s) or channel(s) which you +specify. Takes 2 arguments: the nick or channel to send a message to +(use an array reference here to specify multiple recipients), and the +plain text of the message to send (the CTCP quoting will be handled +for you). The "/me" command in popular IRC clients is actually a CTCP action. + + # Doing a /me + $irc->yield(ctcp => $channel => 'ACTION dances.'); + +=head3 C + +Tells your IRC client to join a single channel of your choice. Takes +at least one arg: the channel name (required) and the channel key +(optional, for password-protected channels). + +=head3 C + +Tell the IRC server to forcibly evict a user from a particular +channel. Takes at least 2 arguments: a channel name, the nick of the +user to boot, and an optional witty message to show them as they sail +out the door. + +=head3 C + +Tell the IRC server to forcibly evict a user from a particular +channel. Takes at least 2 arguments: a channel name, the nick of the +user to boot, and an optional witty message to show them as they sail +out the door. Similar to KICK but does an enforced PART instead. Not +supported by all servers. + +=head3 C + +Request a mode change on a particular channel or user. Takes at least +one argument: the mode changes to effect, as a single string (e.g. +"#mychan +sm-p+o"), and any number of optional operands to the mode changes +(nicks, hostmasks, channel keys, whatever.) Or just pass them all as one +big string and it'll still work, whatever. I regret that I haven't the +patience now to write a detailed explanation, but serious IRC users know +the details anyhow. + +=head3 C + +Allows you to change your nickname. Takes exactly one argument: the +new username that you'd like to be known as. + +=head3 C + +Talks to NickServ, on networks which have it. Takes any number of +arguments. + +=head3 C + +Sends a NOTICE message to the nick(s) or channel(s) which you +specify. Takes 2 arguments: the nick or channel to send a notice to +(use an array reference here to specify multiple recipients), and the +text of the notice to send. + +=head3 C + +Tell your IRC client to leave the channels which you pass to it. Takes +any number of arguments: channel names to depart from. If the last argument +doesn't begin with a channel name identifier or contains a space character, +it will be treated as a PART message and dealt with accordingly. + +=head3 C + +Sends a public or private message to the nick(s) or channel(s) which +you specify. Takes 2 arguments: the nick or channel to send a message +to (use an array reference here to specify multiple recipients), and +the text of the message to send. + +Have a look at the constants in L if you would +like to use formatting and color codes in your messages. + +=head3 C + +Tells the IRC server to disconnect you. Takes one optional argument: +some clever, witty string that other users in your channels will see +as you leave. You can expect to get an +L|/irc_disconnected> event shortly after sending this. + +=head3 C + +By default, POE::Component::IRC sessions never go away. Even after +they're disconnected, they're still sitting around in the background, +waiting for you to call L|/connect> on them again to +reconnect. (Whether this behavior is the Right Thing is doubtful, but I +don't want to break backwards compatibility at this point.) You can send +the IRC session a C event manually to make it delete itself. + +If you are logged into an IRC server, C first will send a quit +message and wait to be disconnected. It will wait for up to 5 seconds before +forcibly disconnecting from the IRC server. If you provide an argument, that +will be used as the QUIT message. If you provide two arguments, the second +one will be used as the timeout (in seconds). + +Terminating multiple components can be tricky. Check the L +section for a method of shutting down multiple poco-ircs. + +=head3 C + +Retrieves or sets the topic for particular channel. If called with just +the channel name as an argument, it will ask the server to return the +current topic. If called with the channel name and a string, it will +set the channel topic to that string. Supply an empty string to unset a +channel topic. + +=head3 C + +Takes one argument: 0 to turn debugging off or 1 to turn debugging on. +This flips the debugging flag in L, +L, and +POE::Component::IRC. This has the same effect as setting Debug in +L|/spawn> or L|/connect>. + +=head2 Not-So-Important Commands + +=head3 C + +Asks your server who your friendly neighborhood server administrators +are. If you prefer, you can pass it a server name to query, instead of +asking the server you're currently on. + +=head3 C + +When sent with an argument (a message describig where you went), the +server will note that you're now away from your machine or otherwise +preoccupied, and pass your message along to anyone who tries to +communicate with you. When sent without arguments, it tells the server +that you're back and paying attention. + +=head3 C + +Used to query/enable/disable IRC protocol capabilities. Takes any number of +arguments. + +=head3 C + +See the L (loaded by default) +documentation for DCC-related commands. + +=head3 C + +Basically the same as the L|/version> command, except that the +server is permitted to return any information about itself that it thinks is +relevant. There's some nice, specific standards-writing for ya, eh? + +=head3 C + +Invites another user onto an invite-only channel. Takes 2 arguments: +the nick of the user you wish to admit, and the name of the channel to +invite them to. + +=head3 C + +Asks the IRC server which users out of a list of nicknames are +currently online. Takes any number of arguments: a list of nicknames +to query the IRC server about. + +=head3 C + +Asks the server for a list of servers connected to the IRC +network. Takes two optional arguments, which I'm too lazy to document +here, so all you would-be linklooker writers should probably go dig up +the RFC. + +=head3 C + +Asks the server for a list of visible channels and their topics. Takes +any number of optional arguments: names of channels to get topic +information for. If called without any channel names, it'll list every +visible channel on the IRC network. This is usually a really big list, +so don't do this often. + +=head3 C + +Request the server's "Message of the Day", a document which typically +contains stuff like the server's acceptable use policy and admin +contact email addresses, et cetera. Normally you'll automatically +receive this when you log into a server, but if you want it again, +here's how to do it. If you'd like to get the MOTD for a server other +than the one you're logged into, pass it the server's hostname as an +argument; otherwise, no arguments. + +=head3 C + +Asks the server for a list of nicknames on particular channels. Takes +any number of arguments: names of channels to get lists of users +for. If called without any channel names, it'll tell you the nicks of +everyone on the IRC network. This is a really big list, so don't do +this much. + +=head3 C + +Sends a raw line of text to the server. Takes one argument: a string +of a raw IRC command to send to the server. It is more optimal to use +the events this module supplies instead of writing raw IRC commands +yourself. + +=head3 C + +Returns some information about a server. Kinda complicated and not +terribly commonly used, so look it up in the RFC if you're +curious. Takes as many arguments as you please. + +=head3 C, an C event will be sent with B<'foo'> as C, +and the rest as given below. + +It is not recommended that you register for both C and C +events, since they will both be fired and presumably cause duplication. + +=head3 C + +C events are generated upon receipt of CTCP messages. +For instance, receiving a CTCP PING request generates an C +event, CTCP ACTION (produced by typing "/me" in most IRC clients) +generates an C event, blah blah, so on and so forth. C +is the nick!hostmask of the sender. C is the channel/recipient +name(s). C is the text of the CTCP message. On servers supporting the +IDENTIFY-MSG feature (e.g. FreeNode), CTCP ACTIONs will have C, which +will be C<1> if the sender has identified with NickServ, C<0> otherwise. + +Note that DCCs are handled separately -- see the +L. + +=head3 C + +C messages are just like C +messages, described above, except that they're generated when a response +to one of your CTCP queries comes back. They have the same arguments and +such as C events. + +=head3 C + +The counterpart to L|/irc_connected>, sent whenever +a socket connection to an IRC server closes down (whether intentionally or +unintentionally). C is the server name. + +=head3 C + +You get this whenever the server sends you an ERROR message. Expect +this to usually be accompanied by the sudden dropping of your +connection. C is the server's explanation of the error. + +=head3 C + +Sent whenever someone joins a channel that you're on. C is the +person's nick!hostmask. C is the channel name. + +=head3 C + +Sent whenever someone offers you an invitation to another channel. C +is the person's nick!hostmask. C is the name of the channel they want +you to join. + +=head3 C + +Sent whenever someone gets booted off a channel that you're on. C +is the kicker's nick!hostmask. C is the channel name. C is the +nick of the unfortunate kickee. C is the explanation string for the +kick. + +=head3 C + +Sent whenever someone changes a channel mode in your presence, or when +you change your own user mode. C is the nick!hostmask of that +someone. C is the channel it affects (or your nick, if it's a user +mode change). C is the mode string (i.e., "+o-b"). The rest of the +args (C) are the operands to the mode string (nicks, +hostmasks, channel keys, whatever). + +=head3 C + +Sent whenever you receive a PRIVMSG command that was addressed to you +privately. C is the nick!hostmask of the sender. C is an array +reference containing the nick(s) of the recipients. C is the text +of the message. On servers supporting the IDENTIFY-MSG feature (e.g. +FreeNode), there will be an additional argument, C, which will be +C<1> if the sender has identified with NickServ, C<0> otherwise. + +=head3 C + +Sent whenever you, or someone around you, changes nicks. C is the +nick!hostmask of the changer. C is the new nick that they changed +to. + +=head3 C + +Sent whenever you receive a NOTICE command. C is the nick!hostmask +of the sender. C is an array reference containing the nick(s) or +channel name(s) of the recipients. C is the text of the NOTICE +message. + +=head3 C + +Sent whenever someone leaves a channel that you're on. C is the +person's nick!hostmask. C is the channel name. C is the part +message. + +=head3 C + +Sent whenever you receive a PRIVMSG command that was sent to a channel. +C is the nick!hostmask of the sender. C is an array +reference containing the channel name(s) of the recipients. C is the +text of the message. On servers supporting the IDENTIFY-MSG feature (e.g. +FreeNode), there will be an additional argument, C, which will be +C<1> if the sender has identified with NickServ, C<0> otherwise. + +=head3 C + +Sent whenever someone on a channel with you quits IRC (or gets +KILLed). C is the nick!hostmask of the person in question. C is +the clever, witty message they left behind on the way out. + +=head3 C + +Sent when a connection couldn't be established to the IRC server. C +is probably some vague and/or misleading reason for what failed. + +=head3 C + +Sent when a channel topic is set or unset. C is the nick!hostmask of the +sender. C is the channel affected. C will be either: a string if the +topic is being set; or a zero-length string (i.e. '') if the topic is being +unset. Note: replies to queries about what a channel topic *is* +(i.e. TOPIC #channel), are returned as numerics, not with this event. + +=head3 C + +Sent in response to a WHOIS query. C is a hashref, with the following +keys: + +=over 4 + +=item * B<'nick'>, the users nickname; + +=item * B<'user'>, the users username; + +=item * B<'host'>, their hostname; + +=item * B<'real'>, their real name; + +=item * B<'idle'>, their idle time in seconds; + +=item * B<'signon'>, the epoch time they signed on (will be undef if ircd +does not support this); + +=item * B<'channels'>, an arrayref listing visible channels they are on, +the channel is prefixed with '@','+','%' depending on whether they have ++o +v or +h; + +=item * B<'server'>, their server (might not be useful on some networks); + +=item * B<'oper'>, whether they are an IRCop, contains the IRC operator +string if they are, undef if they aren't. + +=item * B<'actually'>, some ircds report the users actual ip address, +that'll be here; + +=item * B<'account'> , if the user has registered with services (only on +ircu/seven IRCDs, such as FreeNode) + +=item * B<'identified'>. if the user has identified with NICKSERV (only on +Hyperion IRCDs) + +=back + +=head3 C + +Similar to the above, except some keys will be missing. + +=head3 C + +Enabled by passing C<< Raw => 1 >> to L|/spawn> or +L|/connect>, or by calling L|/raw_events> with +a true argument. C is the raw IRC string received by the component from +the IRC server, before it has been mangled by filters and such like. + +=head3 C + +Enabled by passing C<< Raw => 1 >> to L|/spawn> or +L|/connect>, or by calling L|/raw_events> with +a true argument. C is the raw IRC string sent by the component to the +the IRC server. + +=head3 C + +Emitted by the first event after an L|/All numeric events>, to +indicate that isupport information has been gathered. C is the +L +object. + +=head3 C + +Emitted whenever we fail to connect successfully to a SOCKS server or the +SOCKS server is not actually a SOCKS server. C will be some vague reason +as to what went wrong. Hopefully. + +=head3 C + +Emitted whenever a SOCKS connection is rejected by a SOCKS server. C is +the SOCKS code, C the SOCKS server address, C the SOCKS port and +C the SOCKS user id (if defined). + +=head3 C + +I> + +Emitted whenever a new plugin is added to the pipeline. C is the +plugin alias. C is the plugin object. + +=head3 C + +I> + +Emitted whenever a plugin is removed from the pipeline. C is the +plugin alias. C is the plugin object. + +=head3 C + +I> + +Emitted when an error occurs while executing a plugin handler. C is +the error message. C is the plugin alias. C is the plugin object. + +=head2 Somewhat Less Important Events + +=head3 C + +A reply from the server regarding protocol capabilities. C is the +CAP subcommand (e.g. 'LS'). C is the result of the subcommand, unless +this is a multi-part reply, in which case C is '*' and C contains +the result. + +=head3 C + +See the L (loaded by default) +documentation for DCC-related events. + +=head3 C + +An event sent whenever the server sends a PING query to the +client. (Don't confuse this with a CTCP PING, which is another beast +entirely. If unclear, read the RFC.) Note that POE::Component::IRC will +automatically take care of sending the PONG response back to the +server for you, although you can still register to catch the event for +informational purposes. + +=head3 C + +A weird, non-RFC-compliant message from an IRC server. Usually sent during +to you during an authentication phase right after you connect, while the +server does a hostname lookup or similar tasks. C is the text of the +server's message. C is the target, which could be B<'*'> or B<'AUTH'> +or whatever. Servers vary as to whether these notices include a server name +as the sender, or no sender at all. C is the sender, if any. + +=head3 C + +I> + +Emitted on a successful addition of a delayed event using the +L|/delay> method. C will be the alarm_id which can be used +later with L|/delay_remove>. Subsequent parameters are +the arguments that were passed to L|/delay>. + +=head3 C + +I> + +Emitted when a delayed command is successfully removed. C will be the +alarm_id that was removed. Subsequent parameters are the arguments that were +passed to L|/delay>. + +=head2 All numeric events + +Most messages from IRC servers are identified only by three-digit +numeric codes with undescriptive constant names like RPL_UMODEIS and +ERR_NOTOPLEVEL. (Actually, the list of codes in the RFC is kind of +out-of-date... the list in the back of Net::IRC::Event.pm is more +complete, and different IRC networks have different and incompatible +lists. Ack!) As an example, say you wanted to handle event 376 +(RPL_ENDOFMOTD, which signals the end of the MOTD message). You'd +register for '376', and listen for C events. Simple, no? C +is the name of the server which sent the message. C is the text of +the message. C is an array reference of the parsed message, so there +is no need to parse C yourself. + +=head1 SIGNALS + +The component will handle a number of custom signals that you may send using +L's C method. + +=head2 C + +I> + +Registering with multiple PoCo-IRC components has been a pita. Well, no more, +using the power of L signals. + +If the component receives a C signal it'll register the +requesting session and trigger an L|/irc_registered> +event. From that event one can get all the information necessary such as the +poco-irc object and the SENDER session to do whatever one needs to build a +poco-irc dispatch table. + +The way the signal handler in PoCo-IRC is written also supports sending the +C to multiple sessions simultaneously, by sending the signal +to the POE Kernel itself. + +Pass the signal your session, session ID or alias, and the IRC events (as +specified to L|/register>). + +To register with multiple PoCo-IRCs one can do the following in your session's +_start handler: + + sub _start { + my ($kernel, $session) = @_[KERNEL, SESSION]; + + # Registering with multiple pocoircs for 'all' IRC events + $kernel->signal($kernel, 'POCOIRC_REGISTER', $session->ID(), 'all'); + + return: + } + +Each poco-irc will send your session an +L|/irc_registered> event: + + sub irc_registered { + my ($kernel, $sender, $heap, $irc_object) = @_[KERNEL, SENDER, HEAP, ARG0]; + + # Get the poco-irc session ID + my $sender_id = $sender->ID(); + + # Or it's alias + my $poco_alias = $irc_object->session_alias(); + + # Store it in our heap maybe + $heap->{irc_objects}->{ $sender_id } = $irc_object; + + # Make the poco connect + $irc_object->yield(connect => { }); + + return; + } + +=head2 C + +I> + +Telling multiple poco-ircs to shutdown was a pita as well. The same principle as +with registering applies to shutdown too. + +Send a C to the POE Kernel to terminate all the active +poco-ircs simultaneously. + + $poe_kernel->signal($poe_kernel, 'POCOIRC_SHUTDOWN'); + +Any additional parameters passed to the signal will become your quit messages +on each IRC network. + +=head1 ENCODING + +This can be an issue. Take a look at L +on it. + +=head1 BUGS + +A few have turned up in the past and they are sure to again. Please use +L to report any. Alternatively, email the current +maintainer. + +=head1 DEVELOPMENT + +You can find the latest source on github: +L + +The project's developers usually hang out in the C<#poe> IRC channel on +irc.perl.org. Do drop us a line. + +=head1 MAINTAINERS + +Chris C Williams + +Hinrik Ern SigurEsson + +=head1 AUTHOR + +Dennis Taylor. + +=head1 LICENCE + +Copyright (c) Dennis Taylor, Chris Williams and Hinrik Ern SigurEsson + +This module may be used, modified, and distributed under the same +terms as Perl itself. Please see the license that came with your Perl +distribution for details. + +=head1 MAD PROPS + +The maddest of mad props go out to Rocco "dngor" Caputo +, for inventing something as mind-bogglingly +cool as POE, and to Kevin "oznoid" Lenzo Elenzo@cs.cmu.eduE, +for being the attentive parent of our precocious little infobot on +#perl. + +Further props to a few of the studly bughunters who made this module not +suck: Abys , Addi , ResDev +, and Roderick . Woohoo! + +Kudos to Apocalypse, , for the plugin system and to +Jeff 'japhy' Pinyan, , for Pipeline. + +Thanks to the merry band of POE pixies from #PoE @ irc.perl.org, +including ( but not limited to ), ketas, ct, dec, integral, webfox, +immute, perigrin, paulv, alias. + +IP functions are shamelessly 'borrowed' from L by Manuel +Valente + +Check out the Changes file for further contributors. + +=head1 SEE ALSO + +RFC 1459 L + +L, + +L, + +L, + +Some good examples reside in the POE cookbook which has a whole section +devoted to IRC programming L. + +The examples/ folder of this distribution. + +=cut diff --git a/lib/POE/Component/IRC.pm b/lib/POE/Component/IRC.pm index cca9450b..72a738fb 100644 --- a/lib/POE/Component/IRC.pm +++ b/lib/POE/Component/IRC.pm @@ -1823,7 +1823,7 @@ plans to make it die() >;] =head1 METHODS -=head2 General +=head2 Information =head3 C