From 449e167dce37f49a31564496458a9690c8b1956d Mon Sep 17 00:00:00 2001 From: Adam Frisby Date: Sat, 30 May 2009 07:02:38 +0000 Subject: * You are likely to be eaten by a grue. * Enable with [IRCd] Enabled=true (will listen on port 6666). --- .../InternetRelayClientView/IRCStackModule.cs | 21 ++- .../Server/IRCClientView.cs | 202 +++++++++++++++------ 2 files changed, 162 insertions(+), 61 deletions(-) (limited to 'OpenSim/Region/OptionalModules') diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/IRCStackModule.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/IRCStackModule.cs index c807d7f..9e3e1c7 100644 --- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/IRCStackModule.cs +++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/IRCStackModule.cs @@ -8,7 +8,7 @@ using OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server; namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView { - class IRCStackModule : IRegionModule + public class IRCStackModule : IRegionModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -19,16 +19,25 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView public void Initialise(Scene scene, IConfigSource source) { - m_scene = scene; - m_server = new IRCServer(IPAddress.Parse("0.0.0.0"),6666, scene); - m_server.OnNewIRCClient += m_server_OnNewIRCClient; + if (source.Configs.Contains("IRCd") && + source.Configs["IRCd"].GetBoolean("Enabled",false)) + { + m_scene = scene; + m_server = new IRCServer(IPAddress.Parse("0.0.0.0"), 6666, scene); + m_server.OnNewIRCClient += m_server_OnNewIRCClient; + } } void m_server_OnNewIRCClient(IRCClientView user) { + user.OnIRCReady += user_OnIRCReady; + } + + void user_OnIRCReady(IRCClientView cv) + { m_log.Info("[IRCd] Adding user..."); - m_scene.ClientManager.Add(user.CircuitCode, user); - user.Start(); + m_scene.ClientManager.Add(cv.CircuitCode, cv); + cv.Start(); m_log.Info("[IRCd] Added user to Scene"); } diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs index e87749c..bb20dfd 100644 --- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs +++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.IO; using System.Net; using System.Net.Sockets; using System.Reflection; @@ -14,8 +15,12 @@ using OpenSim.Region.Framework.Scenes; namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server { + public delegate void OnIRCClientReadyDelegate(IRCClientView cv); + public class IRCClientView : IClientAPI, IClientCore, IClientIPEndpoint { + public event OnIRCClientReadyDelegate OnIRCReady; + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private readonly TcpClient m_client; @@ -24,6 +29,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server private UUID m_agentID = UUID.Random(); private string m_username; + private string m_nick; private bool m_hasNick = false; private bool m_hasUser = false; @@ -39,16 +45,23 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server loopThread.Start(); } + private void SendServerCommand(string command) + { + SendCommand(":opensimircd " + command); + } + private void SendCommand(string command) { - lock(m_client) - { - m_log.Info("[IRCd] Sending >>> " + command); + m_log.Info("[IRCd] Sending >>> " + command); - byte[] buf = Encoding.UTF8.GetBytes(command + "\r\n"); + byte[] buf = Encoding.UTF8.GetBytes(command + "\r\n"); - m_client.GetStream().Write(buf, 0, buf.Length); - } + m_client.GetStream().BeginWrite(buf, 0, buf.Length, SendComplete, null); + } + + private void SendComplete(IAsyncResult result) + { + m_log.Info("[IRCd] Send Complete."); } private string IrcRegionName @@ -60,40 +73,67 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server private void InternalLoop() { - string strbuf = ""; - - while(m_connected) + try { - string line; - byte[] buf = new byte[520]; // RFC1459 defines max message size as 512. + string strbuf = ""; - lock (m_client) + while (m_connected && m_client.Connected) { + byte[] buf = new byte[8]; // RFC1459 defines max message size as 512. + int count = m_client.GetStream().Read(buf, 0, buf.Length); - line = Encoding.UTF8.GetString(buf, 0, count); - } + string line = Encoding.UTF8.GetString(buf, 0, count); - strbuf += line; + strbuf += line; - string message = ExtractMessage(strbuf); - if(message != null) - { - m_log.Info("[IRCd] Recieving <<< " + message); + string message = ExtractMessage(strbuf); + if (message != null) + { + // Remove from buffer + strbuf = strbuf.Remove(0, message.Length); + + m_log.Info("[IRCd] Recieving <<< " + message); + message = message.Trim(); - // Remove from buffer - strbuf = strbuf.Remove(0, message.Length); + // Extract command sequence + string command = ExtractCommand(message); + ProcessInMessage(message, command); + } + else + { + //m_log.Info("[IRCd] Recieved data, but not enough to make a message. BufLen is " + strbuf.Length + + // "[" + strbuf + "]"); + if (strbuf.Length == 0) + { + m_connected = false; + m_log.Info("[IRCd] Buffer zero, closing..."); + if (OnDisconnectUser != null) + OnDisconnectUser(); + } + } - // Extract command sequence - string command = ExtractCommand(message); - ProcessInMessage(message, command); + Thread.Sleep(0); } + } + catch (IOException) + { + if (OnDisconnectUser != null) + OnDisconnectUser(); + + m_log.Warn("[IRCd] Disconnected client."); + } + catch (SocketException) + { + if (OnDisconnectUser != null) + OnDisconnectUser(); - Thread.Sleep(0); + m_log.Warn("[IRCd] Disconnected client."); } } private void ProcessInMessage(string message, string command) { + m_log.Info("[IRCd] Processing [MSG:" + message + "] [COM:" + command + "]"); if(command != null) { switch(command) @@ -123,12 +163,11 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server case "SUMMON": case "TIME": case "TRACE": - case "USERHOST": case "VERSION": case "WALLOPS": case "WHOIS": case "WHOWAS": - SendCommand("421 ERR_UNKNOWNCOMMAND \"" + command + " :Command unimplemented\""); + SendServerCommand("421 " + command + " :Command unimplemented"); break; // Connection Commands @@ -141,12 +180,20 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server case "USER": IRC_ProcessUser(message); - IRC_SendReplyJoin(); + IRC_Ready(); + break; + case "USERHOST": + string[] userhostArgs = ExtractParameters(message); + if (userhostArgs[0] == ":" + m_nick) + { + SendServerCommand("302 :" + m_nick + "=+" + m_nick + "@" + + ((IPEndPoint) m_client.Client.RemoteEndPoint).Address); + } break; case "NICK": IRC_ProcessNick(message); - IRC_SendReplyJoin(); + IRC_Ready(); break; case "TOPIC": @@ -164,7 +211,10 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server break; case "NOTICE": // TODO + break; + case "WHO": // TODO + IRC_SendWhoReply(); break; case "PING": @@ -188,31 +238,55 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server break; default: - SendCommand("421 ERR_UNKNOWNCOMMAND \"" + command + " :Unknown command\""); + SendServerCommand("421 " + command + " :Unknown command"); break; } } } - private void IRC_SendReplyJoin() + private void IRC_Ready() { if (m_hasUser && m_hasNick) { - IRC_SendReplyTopic(); - IRC_SendNamesReply(); - IRC_SendChannelPrivmsg("System", "Welcome to Zork^H^H^H OpenSimulator."); - IRC_SendChannelPrivmsg("System", "You are in an open field west of a big white house"); - IRC_SendChannelPrivmsg("System", "with a boarded front door."); + SendServerCommand("001 " + m_nick + " :Welcome to OpenSimulator IRCd"); + SendServerCommand("002 " + m_nick + " :Running OpenSimVersion"); + SendServerCommand("003 " + m_nick + " :This server was created over 9000 years ago"); + SendServerCommand("004 " + m_nick + " :opensimirc r1 aoOirw abeiIklmnoOpqrstv"); + SendServerCommand("251 " + m_nick + " :There are 0 users and 0 services on 1 servers"); + SendServerCommand("252 " + m_nick + " 0 :operators online"); + SendServerCommand("253 " + m_nick + " 0 :unknown connections"); + SendServerCommand("254 " + m_nick + " 1 :channels formed"); + SendServerCommand("255 " + m_nick + " :I have 1 users, 0 services and 1 servers"); + SendCommand(":" + m_nick + " MODE " + m_nick + " :+i"); + SendCommand(":" + m_nick + " JOIN :" + IrcRegionName); + + // Rename to 'Real Name' + SendCommand(":" + m_nick + " NICK :" + m_username.Replace(" ", "")); + m_nick = m_username.Replace(" ", ""); + + IRC_SendReplyJoin(); + IRC_SendChannelPrivmsg("System", "Welcome to OpenSimulator."); + IRC_SendChannelPrivmsg("System", "You are in a maze of twisty little passages, all alike."); + IRC_SendChannelPrivmsg("System", "It is pitch black. You are likely to be eaten by a grue."); + + if (OnIRCReady != null) + OnIRCReady(this); } } + private void IRC_SendReplyJoin() + { + IRC_SendReplyTopic(); + IRC_SendNamesReply(); + } + private void IRC_ProcessUser(string message) { string[] userArgs = ExtractParameters(message); string username = userArgs[0]; string hostname = userArgs[1]; string servername = userArgs[2]; - string realname = userArgs[3]; + string realname = userArgs[3].Replace(":", ""); m_username = realname; m_hasUser = true; @@ -221,7 +295,8 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server private void IRC_ProcessNick(string message) { string[] nickArgs = ExtractParameters(message); - string nickname = nickArgs[0]; + string nickname = nickArgs[0].Replace(":",""); + m_nick = nickname; m_hasNick = true; } @@ -243,7 +318,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server msg.Sender = this; msg.Channel = 0; msg.From = this.Name; - msg.Message = privmsgArgs[1]; + msg.Message = privmsgArgs[1].Replace(":", ""); msg.Position = Vector3.Zero; msg.Scene = m_scene; msg.SenderObject = null; @@ -265,32 +340,45 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server foreach (EntityBase user in users) { - SendCommand("353 RPL_NAMREPLY \"" + IrcRegionName + " :+" + user.Name.Replace(" ", "")); + SendServerCommand("353 " + IrcRegionName + " :+" + user.Name.Replace(" ", "")); } - SendCommand("366 RPL_ENDOFNAMES \"" + IrcRegionName + " :End of /NAMES list\""); + SendServerCommand("366 " + IrcRegionName + " :End of /NAMES list"); + } + + private void IRC_SendWhoReply() + { + List users = m_scene.Entities.GetAllByType(); + + foreach (EntityBase user in users) + { + //:kubrick.freenode.net 352 toblerone3742 #freenode i=nalioth freenode/staff/ubuntu.member.nalioth irc.freenode.net nalioth G :0 http://www.ubuntu.com/donations + //:opensimircd 352 #OpenSim-Test AdamFrisbyIRC nohost.com irc.opensimulator AdamFrisbyIRC H+ :1 Adam FrisbyIRC + SendServerCommand("352 " + user.Name.Replace(" ", "") + " " + IrcRegionName + " nohost.com irc.opensimulator " + user.Name.Replace(" ", "") + " H+ " + ":1 " + user.Name); + } + SendServerCommand("315 " + IrcRegionName + " :End of /WHO list"); } private void IRC_SendMOTD() { - SendCommand("375 RPL_MOTDSTART \":- OpenSimulator Message of the day -"); - SendCommand("372 RPL_MOTD \":- Hiya!"); - SendCommand("376 RPL_ENDOFMOTD \":End of /MOTD command\""); + SendServerCommand("375 :- OpenSimulator Message of the day -"); + SendServerCommand("372 :- Hiya!"); + SendServerCommand("376 :End of /MOTD command"); } private void IRC_SendReplyTopic() { - SendCommand("332 RPL_TOPIC \"" + IrcRegionName + " :OpenSimulator IRC Server\""); + SendServerCommand("332 " + IrcRegionName + " :OpenSimulator IRC Server"); } private void IRC_SendReplyUsers() { List users = m_scene.Entities.GetAllByType(); - - SendCommand("392 RPL_USERSSTART \":UserID Terminal Host\""); + + SendServerCommand("392 :UserID Terminal Host"); if (users.Count == 0) { - SendCommand("395 RPL_NOUSERS \":Nobody logged in\""); + SendServerCommand("395 :Nobody logged in"); return; } @@ -309,10 +397,10 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server nom[i] = ' '; } - SendCommand("393 RPL_USERS \":" + nom + " " + term + " " + host + "\""); + SendServerCommand("393 :" + nom + " " + term + " " + host + ""); } - SendCommand("394 RPL_ENDOFUSERS \":End of users\""); + SendServerCommand("394 :End of users"); } private static string ExtractMessage(string buffer) @@ -322,7 +410,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server if (pos == -1) return null; - string command = buffer.Substring(0, pos + 1); + string command = buffer.Substring(0, pos + 2); return command; } @@ -331,8 +419,11 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server { string[] msgs = msg.Split(' '); - if(msgs.Length < 2) + if (msgs.Length < 2) + { + m_log.Warn("[IRCd] Dropped msg: " + msg); return null; + } if (msgs[0].StartsWith(":")) return msgs[1]; @@ -500,7 +591,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server public uint CircuitCode { - get { return 0; } + get { return (uint)Util.RandomClass.Next(0,int.MaxValue); } } public event GenericMessage OnGenericMessage; @@ -736,7 +827,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server public void SendRegionHandshake(RegionInfo regionInfo, RegionHandshakeArgs args) { - m_log.Info("[MXP ClientStack] Completing Handshake to Region"); + m_log.Info("[IRCd ClientStack] Completing Handshake to Region"); if (OnRegionHandShakeReply != null) { @@ -781,7 +872,8 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server public void SendChatMessage(string message, byte type, Vector3 fromPos, string fromName, UUID fromAgentID, byte source, byte audible) { - IRC_SendChannelPrivmsg(fromName, message); + if (audible > 0) + IRC_SendChannelPrivmsg(fromName, message); } private void IRC_SendChannelPrivmsg(string fromName, string message) -- cgit v1.1