I’ve now got a simple IRC bot that I can control remotely. See previous stories to see the progression and get a feel for where this is going:
.NET Remoting with Mono
.NET Remoting with Mono Part II
Writing IRC bots in Perl and C#
Click below for the latest source code.
Main.cs:
using System;
using Sharkbite.Irc;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
namespace TestCode.Irc
{
public class GemsBotMain
{
public static void Main(string[] args)
{
string[] parameters = Util.ParseArgs( args );
GemsBot bot = new GemsBot( parameters[0],
parameters[1],
parameters[2] );
bot.connection.Connect();
TcpChannel tcp_channel = new TcpChannel(8080);
ChannelServices.RegisterChannel(tcp_channel);
RemotingServices.Marshal(bot, "GemsBot");
Console.WriteLine("GemsBot connected.");
Console.ReadLine();
}
}
}
Util.cs:
using System;
using Sharkbite.Irc;
namespace TestCode.Irc
{
public class Util
{
// Creates a n!u@h user id
public static string BuildUserID ( UserInfo user )
{
return user.Nick + "!" + user.User + "@" + user.Hostname;
}
public static string[] ParseArgs ( string[] args )
{
string arg, value;
// defaults
string[] parameters = new string[] {"gems", "#kos", "boston.ma.us.galaxynet.org"};
foreach (string s in args)
{
int idx = s.IndexOf( ":" );
if (idx == -1){
arg = s;
value = "";
} else {
arg = s.Substring (0, idx);
value = s.Substring (idx + 1);
}
switch ( arg )
{
case "/nick":
parameters[0] = value;
break;
case "/channel":
parameters[1] = value;
break;
case "/server":
parameters[2] = value;
break;
default:
//Usage();
break;
}
}
return parameters;
}
}
}
GemsBot.cs:
using System;
using Sharkbite.Irc;
using System.Text.RegularExpressions;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
namespace TestCode.Irc
{
public class GemsBot : MarshalByRefObject
{
public Connection connection;
private string nick;
private string channel;
private string server;
private Regex auto_op;
public GemsBot( string nick, string channel, string server )
{
this.nick = nick;
this.channel = channel;
this.server = server;
auto_op = new Regex( @"(?ix)skeez.*!~?jamin@.*.dsl.stlsmo.swbell.net|
skeez.*!~?jamin@.*cec.wustl.edu",
RegexOptions.Compiled);
ConnectionArgs cargs = new ConnectionArgs( nick, server );
connection = new Connection( cargs, false, false );
// Set up our handlers
connection.Listener.OnRegistered += new RegisteredEventHandler( OnRegistered );
connection.Listener.OnJoin += new JoinEventHandler( OnJoin );
connection.Listener.OnPublic += new PublicMessageEventHandler( OnPublic );
}
public override Object InitializeLifetimeService()
{
return null;
}
public void OnRegistered()
{
connection.Sender.Join( channel );
Say( "Hey, " + channel + "!" );
}
public void OnJoin( UserInfo user, string channel )
{
string id = Util.BuildUserID( user );
Log( "{0} has joined {1}", id, channel );
if ( auto_op.IsMatch( id ) )
{
connection.Sender.ChangeChannelMode(
channel,
ModeAction.Add,
ChannelMode.ChannelOperator,
user.Nick
);
}
}
public void OnPublic( UserInfo user, string channel, string message )
{
Log( "<{0}> {1}", user.Nick, message );
}
public void Say( string text )
{
connection.Sender.PublicMessage( channel, text );
Log( "<{0}> {1}", nick, text );
}
public void Me( string text )
{
connection.Sender.Action( channel, text );
Log( "* {0} {1}", nick, text );
}
public void Join( string chnl )
{
channel = chnl;
connection.Sender.Join( chnl );
}
public void Log( string format, params object[] arg )
{
Console.WriteLine( format, arg );
}
}
}
RemotingClient.cs:
using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
using System.Text.RegularExpressions;
using Sharkbite.Irc;
namespace TestCode.Irc
{
public class RemotingClient
{
public static void Main(string [] args)
{
TcpChannel chan = new TcpChannel();
ChannelServices.RegisterChannel(chan);
string command;
Regex rCommand = new Regex( @"(?<cmd>w+)s+(?<args>.*)" ,
RegexOptions.Compiled );
Match m;
GemsBot obj = (GemsBot) Activator.GetObject(
typeof(TestCode.Irc.GemsBot),
"tcp://localhost:8080/GemsBot" );
while (true)
{
string remote_cmd;
string remote_args;
Console.Write("RemoteIrc command> ");
command = Console.ReadLine();
if (command == "quit" || command == "exit")
{
break;
}
else
{
// Split the text into the command and the arguments
m = rCommand.Match( command );
if ( m.Success )
{
remote_cmd = m.Groups["cmd"].Value;
remote_args = m.Groups["args"].Value;
switch ( remote_cmd )
{
case "say":
obj.Say( remote_args );
break;
case "me":
obj.Me( remote_args );
break;
case "join":
obj.Join( remote_args );
break;
default:
Console.WriteLine("Unknown Command. Try again...");
break;
}
}
}
}
}
}
}
Makefile:
CSC=mcs --debug default: all Main.exe: Main.cs GemsBot.dll Util.dll $(CSC) /r:IRC.dll /r:GemsBot.dll /r:Util.dll /r:System.Runtime.Remoting $< RemotingClient.exe: RemotingClient.cs GemsBot.dll $(CSC) /r:GemsBot.dll /r:System.Runtime.Remoting $< Util.dll: Util.cs $(CSC) /r:IRC.dll /target:library $< GemsBot.dll: GemsBot.cs Util.dll $(CSC) /r:IRC.dll /r:Util.dll /target:library $< all: GemsBot.dll Util.dll Main.exe RemotingClient.exe clean: rm -f *.dll *.exe
Tags: Mono









