Using SmartIrc4net - IrcClient
(Page 4 of 4 )
IrcClient is the third and final layer of SmartIrc4net. It is a subclass of IrcCommands, and it provides the most functionality. It only defines a few more methods and properties, but it makes a great many more events available. It's possible to create a very event-driven application using IrcClient. Let's put together a very basic application upon which we can expand:
using Meebey.SmartIrc4net;
using System;
using System.Collections.Generic;
using System.Text;
class ClientDemo
{
private IrcClientirc = new IrcClient();
private string server = "irc.freenode.com";
private int port = 6667;
private static void Main()
{
ClientDemo demo = new ClientDemo();
}
public ClientDemo()
{
irc.OnConnected += new EventHandler(OnConnected);
try
{
irc.Connect(server, port);
}
catch (Exception e)
{
Console.Write("Failed to connect:n"+ e.Message);
Console.ReadKey();
}
}
void OnConnected(object sender, EventArgs e)
{
irc.Login("CSharp", "CSharp Bot", 0, "CSharp");
irc.RfcJoin(channel);
irc.Listen();
}
}
In the above application, the Login method is used rather than the Nick and User methods. There are several constructors for this method, but the one we use takes arguments for the username, real name, userlevel and nickname, respectively.
Notice how the application doesn't respond to ping messages. This is because IrcClient handles them automatically. However, it's still possible to respond to ping messages in case extra handling is necessary. Instead of subscribing to OnReadLine as was done before, however, we can subscribe to OnPing:
irc.OnPing += new PingEventHandler(OnPing);
Then we can provide an event handler:
void OnPing(object sender, PingEventArgs e)
{
Console.WriteLine("Responded to ping at {0}.",
DateTime.Now.ToShortTimeString());
}
The IrcClient class contains many events similar to OnPing. Not all of them can be covered in this article, but we will take a look at OnQueryMessage and OnChannelMessage, which are triggered by personal messages and channel messages:
irc.OnChannelMessage += new IrcEventHandler(OnChannelMessage);
irc.OnQueryMessage += new IrcEventHandler(OnQueryMessage);
IrcEventHandler contains a member named Data of the type IrcMessageData, which describes a message. IrcMessageData has properties that describe things such as the channel the message comes from, the nickname of the person who sent it and the type of the message. Here, we use some of these properties when we respond to the two events:
void OnChannelMessage(object sender, IrcEventArgs e)
{
Console.WriteLine(e.Data.Type + ":");
Console.WriteLine("("+ e.Data.Channel + ") <"+
e.Data.Nick + "> "+ e.Data.Message);
}
void OnQueryMessage(object sender, IrcEventArgs e)
{
Console.WriteLine(e.Data.Type + ":");
Console.WriteLine("(private) <"+ e.Data.Nick + "> "+
e.Data.Message);
}
The final feature I'd like to point out in IrcClient is the ability to keep track of channels over time. This feature is named active channel syncing and has to be enabled before it can be used:
irc.ActiveChannelSyncing = true;
To demonstrate active channel syncing, we'll revise OnQueryMessage to examine incoming messages for the commands "!list" and "!info." If the former command is received, the querying user will be sent a list of channels that the application is currently in. If the latter command is received, along with a channel (for example, "!info #smartirc4net_test"), then some basic information about that channel will be sent to the querying user:
void OnQueryMessage(object sender, IrcEventArgs e)
{
if (e.Data.MessageArray[0] == "!list")
{
string channels = String.Join(", ", irc.GetChannels
());
irc.SendMessage(SendType.Message, e.Data.Nick,
channels);
}
else if (e.Data.MessageArray[0] == "!info")
{
Channel channel = irc.GetChannel(e.Data.MessageArray
[1]);
List<string> userList = new List<string>();
foreach (ChannelUseruser in channel.Users.Values)
{
string nick = user.Nick;
if (user.IsOp)
nick = "@"+ nick;
else if (user.IsVoice)
nick = "+"+ nick;
userList.Add(nick);
}
string users = String.Join(", ", userList.ToArray());
irc.SendMessage(SendType.Message, e.Data.Nick,
channel.Name);
irc.SendMessage(SendType.Message, e.Data.Nick,
"Topic: "+ channel.Topic);
irc.SendMessage(SendType.Message, e.Data.Nick,
"Users: "+ users);
}
}
The first situation is pretty simple. The GetChannels method returns an array of strings representing channel names. The strings are joined together, and the resulting string is sent to the user. In the second situation, the GetChannel method is used to retrieve a Channel object representing the given channel. The channel name, the channel topic and a list of channel users are sent to the querying user. The users are obtained by examining the Users Hashtable. We extract a ChannelUser object for each user in the channel, and we format a nickname string depending on the user being opped or voiced.
Conclusion
The SmartIrc4net library offers users both flexibility and power in developing IRC-enabled applications by providing three layers of connectivity: IrcConnection, IrcCommands and IrcClient, each layer built upon the previous one. The library allows developers to build event-driven applications, too, which eliminates unnecessary coding. The SmartIrc4net library proves that working with IRC through .NET is not difficult at all.
| DISCLAIMER: The content provided in this article is not warranted or guaranteed by Developer Shed, Inc. The content provided is intended for entertainment and/or educational purposes in order to introduce to the reader key ideas, concepts, and/or product reviews. As such it is incumbent upon the reader to employ real-world tactics for security and implementation of best practices. We are not liable for any negative consequences that may result from implementing any information covered in our articles or tutorials. If this is a hardware review, it is not recommended to open and/or modify your hardware. |