LIBOMV-486: Added IRC <-> SL gateway example

git-svn-id: http://libopenmetaverse.googlecode.com/svn/libopenmetaverse/trunk@2589 52acb1d6-8a22-11de-b505-999d5b087335
This commit is contained in:
2009-04-10 21:23:34 +00:00
parent f48c9922e9
commit e759da3fd6
3 changed files with 268 additions and 0 deletions

View File

@@ -0,0 +1,158 @@
using System;
using System.Net.Sockets;
using System.Text;
using System.Threading;
public class IRCClient
{
private TcpClient ircClient;
private bool Shutdown = false;
private string ServerHost;
private int ServerPort;
private string Nickname;
private string RealName = String.Empty;
private Thread LoopThread;
private Thread ConnectThread;
public delegate void ConnectCallback();
public event ConnectCallback OnConnectFail;
public event ConnectCallback OnConnected;
public event ConnectCallback OnDisconnected;
public delegate void DataCallback(string data);
public event DataCallback OnData;
public delegate void MessageCallback(string target, string name, string address, string message);
public event MessageCallback OnMessage;
/// <summary>
/// Basic class for a threaded, sychronous TCP client with built-in functions and events for IRC connectivity
/// </summary>
/// <param name="serverHost"></param>
/// <param name="port"></param>
/// <param name="nickname"></param>
/// <param name="realName"></param>
public IRCClient(string serverHost, int port, string nickname, string realName)
{
ircClient = new TcpClient();
ServerHost = serverHost;
ServerPort = port;
Nickname = nickname;
RealName = realName;
}
/// <summary>
/// Connect to IRC network
/// </summary>
public void Connect()
{
ConnectThread = new Thread(new ThreadStart(ConnectThreadStart));
ConnectThread.Start();
}
/// <summary>
/// Connect to IRC network with the specified parameters
/// </summary>
/// <param name="serverHost"></param>
/// <param name="port"></param>
/// <param name="nickname"></param>
/// <param name="realName"></param>
public void Connect(string serverHost, int port, string nickname, string realName)
{
ServerHost = serverHost;
ServerPort = port;
Nickname = nickname;
RealName = realName;
Connect();
}
/// <summary>
/// Join an IRC channel
/// </summary>
/// <param name="channel"></param>
public void JoinChannel(string channel)
{
ircClient.Client.Send(Encoding.ASCII.GetBytes("JOIN " + channel + "\r\n"));
}
/// <summary>
/// Send a message to the specified nickname or channel
/// </summary>
/// <param name="target"></param>
/// <param name="message"></param>
public void SendMessage(string target, string message)
{
ircClient.Client.Send(Encoding.ASCII.GetBytes("PRIVMSG " + target + " :" + message + "\r\n"));
}
private void ConnectThreadStart()
{
ircClient.Connect(ServerHost, ServerPort);
if (!ircClient.Connected)
{
if (OnConnectFail != null)
OnConnectFail();
return;
}
ircClient.Client.Send(Encoding.ASCII.GetBytes("USER " + Nickname + " x x :" + RealName + "\r\n"));
ircClient.Client.Send(Encoding.ASCII.GetBytes("NICK " + Nickname + "\r\n"));
LoopThread = new Thread(new ThreadStart(LoopThreadStart));
LoopThread.Start();
}
private void LoopThreadStart()
{
while (!Shutdown && ircClient.Connected)
{
byte[] buffer = new byte[4096];
ircClient.Client.Receive(buffer);
if (buffer.Length == 0) break;
string[] lines = Encoding.ASCII.GetString(buffer).Split(new string[] { "\r\n", "\n", "\r" }, StringSplitOptions.RemoveEmptyEntries);
for(int i=0; i<lines.Length - 1; i++)
{
string[] words = lines[i].Split(new char[] { ' ' });
if (OnData != null && lines[i].Length > 0)
OnData(lines[i]);
if (words.Length < 2) return;
if (words[0].ToUpper() == "PING")
ircClient.Client.Send(Encoding.ASCII.GetBytes("PONG " + words[1] + "\r\n"));
else if (words[1] == "001")
{
if (OnConnected != null)
OnConnected();
}
else if (words[1].ToUpper() == "PRIVMSG")
{
if (OnMessage != null)
{
int nameIndex = words[0].IndexOf('!');
string name = words[0].Substring(1, nameIndex - 1);
string address = words[0].Substring(nameIndex + 1);
OnMessage(words[2], name, address, lines[i].Substring(lines[i].IndexOf(":", 1) + 1));
}
}
}
}
if (!ircClient.Connected)
{
if (OnDisconnected != null)
OnDisconnected();
}
else ircClient.Close();
}
}

View File

@@ -0,0 +1,85 @@
using OpenMetaverse;
using System;
namespace IRCGateway
{
class Program
{
static GridClient _Client;
static LoginParams _ClientLogin;
static IRCClient _IRC;
static string _AutoJoinChannel;
static UUID _MasterID;
static void Main(string[] args)
{
int ircPort;
if (args.Length < 7 || !UUID.TryParse(args[3], out _MasterID) || !int.TryParse(args[5], out ircPort) || args[6].IndexOf('#') == -1)
Console.WriteLine("Usage: ircgateway.exe <firstName> <lastName> <password> <masterUUID> <ircHost> <ircPort> <#channel>");
else
{
_Client = new GridClient();
_Client.Network.OnLogin += new NetworkManager.LoginCallback(Network_OnLogin);
_Client.Self.OnChat += new AgentManager.ChatCallback(Self_OnChat);
_Client.Self.OnInstantMessage += new AgentManager.InstantMessageCallback(Self_OnInstantMessage);
_ClientLogin = _Client.Network.DefaultLoginParams(args[0], args[1], args[2], "", "IRCGateway");
_AutoJoinChannel = args[6];
_IRC = new IRCClient(args[4], ircPort, "SLGateway", "Second Life Gateway");
_IRC.OnConnected += new IRCClient.ConnectCallback(_IRC_OnConnected);
_IRC.OnMessage += new IRCClient.MessageCallback(_IRC_OnMessage);
_IRC.Connect();
string read = Console.ReadLine();
while (read != null) read = Console.ReadLine();
}
}
static void _IRC_OnConnected()
{
_IRC.JoinChannel(_AutoJoinChannel);
_Client.Network.BeginLogin(_ClientLogin);
}
static void _IRC_OnMessage(string target, string name, string address, string message)
{
if (target == _AutoJoinChannel)
{
string str = "<" + name + "> " + message;
_Client.Self.Chat(str, 0, ChatType.Normal);
Console.WriteLine("[IRC->SL] " + str);
}
}
static void Self_OnInstantMessage(InstantMessage im, Simulator simulator)
{
if (im.Dialog == InstantMessageDialog.RequestTeleport)
{
if (im.FromAgentID == _MasterID)
{
_Client.Self.TeleportLureRespond(im.FromAgentID, true);
}
}
}
static void Network_OnLogin(LoginStatus login, string message)
{
_IRC.SendMessage(_AutoJoinChannel, message);
}
static void Self_OnChat(string message, ChatAudibleLevel audible, ChatType type, ChatSourceType sourceType, string fromName, UUID id, UUID ownerid, Vector3 position)
{
if (fromName != _Client.Self.Name && type == ChatType.Normal && audible == ChatAudibleLevel.Fully)
{
string str = "<" + fromName + "> " + message;
_IRC.SendMessage(_AutoJoinChannel, str);
Console.WriteLine("[SL->IRC] " + str);
}
}
}
}