libircpp manual

Welcome to the libircpp manual.
  1. Introduction
  2. Hello World
  3. Compiling and installing
  4. Signals
  5. Example: op-me bot
  6. Messages
  7. Users and Channels
  8. User and Channel Lists
  9. Example: Channel Logger
  10. Planned features

7. Users and Channels

What the hell is an Entity?

Users and channels on IRC share many characteristics - for example, you can send messages to them, and set modes on them. In many places, the IRC protocol contains parameters where either a user or a channel may be specified.

Therefore, libircpp derives both the user and channel class from a common ancestor, unimaginatively called an entity. The entity class is used wherever a user or channel could be equally valid - for example, the recipient of messages is an entity.

Entity functions

The entity object contains functions that are equally valid for both a user and a channel:
name()          // Retrieves the channel's name or user's nick (you can also use nick())
cmd_privmsg()  	// Sends a privmsg to the user or channel
cmd_notice()    // Sends a notice to the user or channel
cmd_ctcp()      // Sends a CTCP message to the user or channel
cmd_action()    // Sends a CTCP ACTION (/me) to the user or channel
You may use these functions without having to convert the entity to a user or a channel. For operations more specific to users or channels, you must convert the entity object into either a user or a channel first

Entity signals

Similarly, entity objects have the following signals, which you can connect to because both users and channels can receive privmsgs, notices, and ctcps:
sig_privmsg_msg    // Emitted when a privmsg is recieved for the user or channel
sig_notice_msg     // Emitted when a notice is received for the user or channel
sig_ctcp_msg       // Emitted when a CTCP message is received for the user or channel

Converting entity objects

An entity object will represent either a user or a channel, and contains functions to allow you to find out which it is, and to convert it into the appropriate object.

is_user() and is_channel() will return true if the entity is a user or a channel respectively. to_user() and to_channel() will return a reference to the object correctly cast to a user or a channel respectively. You can use them like this:

if(msg.to().is_channel()) {
	// It's a channel
	const channel& c = msg.to().to_channel();
	// Now do channel stuff using channel object c
}
else if(msg.to().is_user()) {
	// It's a user
	const user& u = msg.to().to_user();
	// Now do user stuff using user object u
}
To appease the C++ purists who are now jumping up and down shouting "dynamic_cast!" - yes, you can use dynamic_cast to convert the entity to a user or channel. The convenience functions mentioned above are for those who don't want to deal with exceptions.

If you call to_channel() on an entity that is a user, the null channel object will be returned. Similarly, if you call to_user() on an entity that is a channel, the null user object will be returned. So an alternative way of converting entities is:

channel& c = msg.to().to_channel();
if(c) {
	// It's a channel, do channel stuff here
}

Users

The user object, predictably, represents one user on irc. All messages will contain a reference to at least one user object. The user object allows you to retrieve information, receive events, and send commands related to the user it represents.

Information functions

The user object lets you retrieve information about the user via the following function:
u.nick();		// Returns the user's nickname
username();		// Returns the user's username (ident)
hostname();		// Returns the user's hostname (IP)
realname();		// Returns the user's realneame (gecos)
The nick() function will always be available, but the username(), hostname() and realname() data may not be available. This is because, upon joining a channel, only a list of nicks is provided by the irc server. When a user sends a privmsg or notice, the username and hostname are sent, and libircpp then saves the appropriate data in the user object. The realname can only be retrieved from a /whois or /who reply. So, if you need to ensure that all the data is available, you must do a cmd_who or cmd_whois on the user, and wait for the appropriate whois or who reply, before calling the information functions.

User signals

The user object inherits sig_privmsg_msg, sig_notice_msg, and sig_ctcp_msg from the entity object. In addition, user objects have a sig_nick_msg signal, which is emitted when the user changes nick. It contains the NICK command recieved from the server. Note that when you receive this signal, the user's nickname as returned by nick() will still be the old nick. The new nick is contained within the NICK message object. After returning from your signal handler, the user object is updated. This is to allow you to easily find any references you may have to the user by referring to the user object, before it is updated with the new nickname.

The "me" and "server" users

There are two "special" user objects which are created by the session object. These are the "me" user object, representing yourself on irc, and the "server" user object, which represents the server to which you are connected. The server is represented as a user, because it sends messages, and can do things like setting modes on a channel (after a netsplit, for example). You can retrieve these two user objects with the session object's me() and server() functions. The "me" object will also be included in channel userlists. The "me" object can be used to retrieve your own nick, username, hostname, and realname. The server object only has a meaningful nickname, which will be the server's name as seen on irc (e.g. irc.somenetwork.net).

Channels

The channel object represents a channel you are in. You will typically receive a reference to it in a message object, and it can be used to retrieve information or receive events about the channel, or send commands related to the channel.

Information functions

In addition to the name() function inherited from the entity object, the channel has a topic() function which returns the channel topic.

Channel signals

The channel object has the following signals you can connect to.
sig_join_msg            // Emitted when anyone (including you) joins the channel
sig_part_msg            // Emitted when anyone (including you) parts from the channel
sig_quit_msg            // Emitted when anyone in the channel (including you) quits IRC
sig_mode_msg            // Emitted when a mode on the channel is changed
sig_singlemode_msg      // Emitted for each individual mode change on the channel
sig_topic_msg           // Emitted when the channel topic is changed
sig_kick_ms             // Emitted when someone is kicked from the channel
sig_invite_msg          // Emitted when someone is invited to the channel
sig_numeric             // Emitted when a numeric message for the channel is recieved
Most of these signals mirror signals emitted by the session object. The difference between these signals and the session object's signals is that these signals are only emitted for messages to this channel. The session object signals are emitted for messages to all channels.

For more information on the sig_singlemode_msg signal, please see the section on mode messages in the messages chapter.

Channel commands

The channel object also has the following command functions that can be used to perform commands related to the channel:
cmd_part()              // Causes you to leave the channel
cmd_topic()             // Changes the channel topic
cmd_kick()				// Kicks someone from the channel
cmd_invite()            // Invites someone to the channel
cmd_names()             // Requests a list of names of the occupants of the channel
Again, most of these mirror commands available in the session object, but do not require the name parameter as they relate to the channel object they are called on. There is no cmd_join() function as the channel object is only created when the channel is successfully joined. To join a channel, use the session object's cmd_join() with the channel's name. If the join is successful, you can retrieve the channel object's reference from the sig_join_msg signal.

The null user and channel objects

The session object contains two special objects - the null user and the null channel. These are used where no valid user or channel is present, for example where no recipient or target exists in a message. Their names are always blank, and they return false if used in boolean context. This means you can test whether a user or channel is valid simply like this:
if(u) {
		// The user is valid
}

if(!c) {
		// No valid channel object
}

if(msg.target()) {
		// The message has a target 
}
This arrangement also means it is always valid to do things like:
cout << "Recipient: " << msg.to().name() << endl;
If the message has no recipient, the null user will be used, and the name printed will be blank - but will not throw an exception or cause any errors.

If you need a reference to the null user or channel object directly, they can be retrieved with the session's functions:

s.nulluser();       // Returns the null user
s.nullchannel();    // Returns the null channel
Next: User and Channel Lists