aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/IRCStackModule.cs21
-rw-r--r--OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs202
2 files changed, 162 insertions, 61 deletions
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;
8 8
9namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView 9namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView
10{ 10{
11 class IRCStackModule : IRegionModule 11 public class IRCStackModule : IRegionModule
12 { 12 {
13 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 13 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
14 14
@@ -19,16 +19,25 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView
19 19
20 public void Initialise(Scene scene, IConfigSource source) 20 public void Initialise(Scene scene, IConfigSource source)
21 { 21 {
22 m_scene = scene; 22 if (source.Configs.Contains("IRCd") &&
23 m_server = new IRCServer(IPAddress.Parse("0.0.0.0"),6666, scene); 23 source.Configs["IRCd"].GetBoolean("Enabled",false))
24 m_server.OnNewIRCClient += m_server_OnNewIRCClient; 24 {
25 m_scene = scene;
26 m_server = new IRCServer(IPAddress.Parse("0.0.0.0"), 6666, scene);
27 m_server.OnNewIRCClient += m_server_OnNewIRCClient;
28 }
25 } 29 }
26 30
27 void m_server_OnNewIRCClient(IRCClientView user) 31 void m_server_OnNewIRCClient(IRCClientView user)
28 { 32 {
33 user.OnIRCReady += user_OnIRCReady;
34 }
35
36 void user_OnIRCReady(IRCClientView cv)
37 {
29 m_log.Info("[IRCd] Adding user..."); 38 m_log.Info("[IRCd] Adding user...");
30 m_scene.ClientManager.Add(user.CircuitCode, user); 39 m_scene.ClientManager.Add(cv.CircuitCode, cv);
31 user.Start(); 40 cv.Start();
32 m_log.Info("[IRCd] Added user to Scene"); 41 m_log.Info("[IRCd] Added user to Scene");
33 } 42 }
34 43
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 @@
1using System; 1using System;
2using System.Collections.Generic; 2using System.Collections.Generic;
3using System.IO;
3using System.Net; 4using System.Net;
4using System.Net.Sockets; 5using System.Net.Sockets;
5using System.Reflection; 6using System.Reflection;
@@ -14,8 +15,12 @@ using OpenSim.Region.Framework.Scenes;
14 15
15namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server 16namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
16{ 17{
18 public delegate void OnIRCClientReadyDelegate(IRCClientView cv);
19
17 public class IRCClientView : IClientAPI, IClientCore, IClientIPEndpoint 20 public class IRCClientView : IClientAPI, IClientCore, IClientIPEndpoint
18 { 21 {
22 public event OnIRCClientReadyDelegate OnIRCReady;
23
19 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 24 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
20 25
21 private readonly TcpClient m_client; 26 private readonly TcpClient m_client;
@@ -24,6 +29,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
24 private UUID m_agentID = UUID.Random(); 29 private UUID m_agentID = UUID.Random();
25 30
26 private string m_username; 31 private string m_username;
32 private string m_nick;
27 33
28 private bool m_hasNick = false; 34 private bool m_hasNick = false;
29 private bool m_hasUser = false; 35 private bool m_hasUser = false;
@@ -39,16 +45,23 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
39 loopThread.Start(); 45 loopThread.Start();
40 } 46 }
41 47
48 private void SendServerCommand(string command)
49 {
50 SendCommand(":opensimircd " + command);
51 }
52
42 private void SendCommand(string command) 53 private void SendCommand(string command)
43 { 54 {
44 lock(m_client) 55 m_log.Info("[IRCd] Sending >>> " + command);
45 {
46 m_log.Info("[IRCd] Sending >>> " + command);
47 56
48 byte[] buf = Encoding.UTF8.GetBytes(command + "\r\n"); 57 byte[] buf = Encoding.UTF8.GetBytes(command + "\r\n");
49 58
50 m_client.GetStream().Write(buf, 0, buf.Length); 59 m_client.GetStream().BeginWrite(buf, 0, buf.Length, SendComplete, null);
51 } 60 }
61
62 private void SendComplete(IAsyncResult result)
63 {
64 m_log.Info("[IRCd] Send Complete.");
52 } 65 }
53 66
54 private string IrcRegionName 67 private string IrcRegionName
@@ -60,40 +73,67 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
60 73
61 private void InternalLoop() 74 private void InternalLoop()
62 { 75 {
63 string strbuf = ""; 76 try
64
65 while(m_connected)
66 { 77 {
67 string line; 78 string strbuf = "";
68 byte[] buf = new byte[520]; // RFC1459 defines max message size as 512.
69 79
70 lock (m_client) 80 while (m_connected && m_client.Connected)
71 { 81 {
82 byte[] buf = new byte[8]; // RFC1459 defines max message size as 512.
83
72 int count = m_client.GetStream().Read(buf, 0, buf.Length); 84 int count = m_client.GetStream().Read(buf, 0, buf.Length);
73 line = Encoding.UTF8.GetString(buf, 0, count); 85 string line = Encoding.UTF8.GetString(buf, 0, count);
74 }
75 86
76 strbuf += line; 87 strbuf += line;
77 88
78 string message = ExtractMessage(strbuf); 89 string message = ExtractMessage(strbuf);
79 if(message != null) 90 if (message != null)
80 { 91 {
81 m_log.Info("[IRCd] Recieving <<< " + message); 92 // Remove from buffer
93 strbuf = strbuf.Remove(0, message.Length);
94
95 m_log.Info("[IRCd] Recieving <<< " + message);
96 message = message.Trim();
82 97
83 // Remove from buffer 98 // Extract command sequence
84 strbuf = strbuf.Remove(0, message.Length); 99 string command = ExtractCommand(message);
100 ProcessInMessage(message, command);
101 }
102 else
103 {
104 //m_log.Info("[IRCd] Recieved data, but not enough to make a message. BufLen is " + strbuf.Length +
105 // "[" + strbuf + "]");
106 if (strbuf.Length == 0)
107 {
108 m_connected = false;
109 m_log.Info("[IRCd] Buffer zero, closing...");
110 if (OnDisconnectUser != null)
111 OnDisconnectUser();
112 }
113 }
85 114
86 // Extract command sequence 115 Thread.Sleep(0);
87 string command = ExtractCommand(message);
88 ProcessInMessage(message, command);
89 } 116 }
117 }
118 catch (IOException)
119 {
120 if (OnDisconnectUser != null)
121 OnDisconnectUser();
122
123 m_log.Warn("[IRCd] Disconnected client.");
124 }
125 catch (SocketException)
126 {
127 if (OnDisconnectUser != null)
128 OnDisconnectUser();
90 129
91 Thread.Sleep(0); 130 m_log.Warn("[IRCd] Disconnected client.");
92 } 131 }
93 } 132 }
94 133
95 private void ProcessInMessage(string message, string command) 134 private void ProcessInMessage(string message, string command)
96 { 135 {
136 m_log.Info("[IRCd] Processing [MSG:" + message + "] [COM:" + command + "]");
97 if(command != null) 137 if(command != null)
98 { 138 {
99 switch(command) 139 switch(command)
@@ -123,12 +163,11 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
123 case "SUMMON": 163 case "SUMMON":
124 case "TIME": 164 case "TIME":
125 case "TRACE": 165 case "TRACE":
126 case "USERHOST":
127 case "VERSION": 166 case "VERSION":
128 case "WALLOPS": 167 case "WALLOPS":
129 case "WHOIS": 168 case "WHOIS":
130 case "WHOWAS": 169 case "WHOWAS":
131 SendCommand("421 ERR_UNKNOWNCOMMAND \"" + command + " :Command unimplemented\""); 170 SendServerCommand("421 " + command + " :Command unimplemented");
132 break; 171 break;
133 172
134 // Connection Commands 173 // Connection Commands
@@ -141,12 +180,20 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
141 180
142 case "USER": 181 case "USER":
143 IRC_ProcessUser(message); 182 IRC_ProcessUser(message);
144 IRC_SendReplyJoin(); 183 IRC_Ready();
184 break;
145 185
186 case "USERHOST":
187 string[] userhostArgs = ExtractParameters(message);
188 if (userhostArgs[0] == ":" + m_nick)
189 {
190 SendServerCommand("302 :" + m_nick + "=+" + m_nick + "@" +
191 ((IPEndPoint) m_client.Client.RemoteEndPoint).Address);
192 }
146 break; 193 break;
147 case "NICK": 194 case "NICK":
148 IRC_ProcessNick(message); 195 IRC_ProcessNick(message);
149 IRC_SendReplyJoin(); 196 IRC_Ready();
150 197
151 break; 198 break;
152 case "TOPIC": 199 case "TOPIC":
@@ -164,7 +211,10 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
164 break; 211 break;
165 212
166 case "NOTICE": // TODO 213 case "NOTICE": // TODO
214 break;
215
167 case "WHO": // TODO 216 case "WHO": // TODO
217 IRC_SendWhoReply();
168 break; 218 break;
169 219
170 case "PING": 220 case "PING":
@@ -188,31 +238,55 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
188 break; 238 break;
189 239
190 default: 240 default:
191 SendCommand("421 ERR_UNKNOWNCOMMAND \"" + command + " :Unknown command\""); 241 SendServerCommand("421 " + command + " :Unknown command");
192 break; 242 break;
193 } 243 }
194 } 244 }
195 } 245 }
196 246
197 private void IRC_SendReplyJoin() 247 private void IRC_Ready()
198 { 248 {
199 if (m_hasUser && m_hasNick) 249 if (m_hasUser && m_hasNick)
200 { 250 {
201 IRC_SendReplyTopic(); 251 SendServerCommand("001 " + m_nick + " :Welcome to OpenSimulator IRCd");
202 IRC_SendNamesReply(); 252 SendServerCommand("002 " + m_nick + " :Running OpenSimVersion");
203 IRC_SendChannelPrivmsg("System", "Welcome to Zork^H^H^H OpenSimulator."); 253 SendServerCommand("003 " + m_nick + " :This server was created over 9000 years ago");
204 IRC_SendChannelPrivmsg("System", "You are in an open field west of a big white house"); 254 SendServerCommand("004 " + m_nick + " :opensimirc r1 aoOirw abeiIklmnoOpqrstv");
205 IRC_SendChannelPrivmsg("System", "with a boarded front door."); 255 SendServerCommand("251 " + m_nick + " :There are 0 users and 0 services on 1 servers");
256 SendServerCommand("252 " + m_nick + " 0 :operators online");
257 SendServerCommand("253 " + m_nick + " 0 :unknown connections");
258 SendServerCommand("254 " + m_nick + " 1 :channels formed");
259 SendServerCommand("255 " + m_nick + " :I have 1 users, 0 services and 1 servers");
260 SendCommand(":" + m_nick + " MODE " + m_nick + " :+i");
261 SendCommand(":" + m_nick + " JOIN :" + IrcRegionName);
262
263 // Rename to 'Real Name'
264 SendCommand(":" + m_nick + " NICK :" + m_username.Replace(" ", ""));
265 m_nick = m_username.Replace(" ", "");
266
267 IRC_SendReplyJoin();
268 IRC_SendChannelPrivmsg("System", "Welcome to OpenSimulator.");
269 IRC_SendChannelPrivmsg("System", "You are in a maze of twisty little passages, all alike.");
270 IRC_SendChannelPrivmsg("System", "It is pitch black. You are likely to be eaten by a grue.");
271
272 if (OnIRCReady != null)
273 OnIRCReady(this);
206 } 274 }
207 } 275 }
208 276
277 private void IRC_SendReplyJoin()
278 {
279 IRC_SendReplyTopic();
280 IRC_SendNamesReply();
281 }
282
209 private void IRC_ProcessUser(string message) 283 private void IRC_ProcessUser(string message)
210 { 284 {
211 string[] userArgs = ExtractParameters(message); 285 string[] userArgs = ExtractParameters(message);
212 string username = userArgs[0]; 286 string username = userArgs[0];
213 string hostname = userArgs[1]; 287 string hostname = userArgs[1];
214 string servername = userArgs[2]; 288 string servername = userArgs[2];
215 string realname = userArgs[3]; 289 string realname = userArgs[3].Replace(":", "");
216 290
217 m_username = realname; 291 m_username = realname;
218 m_hasUser = true; 292 m_hasUser = true;
@@ -221,7 +295,8 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
221 private void IRC_ProcessNick(string message) 295 private void IRC_ProcessNick(string message)
222 { 296 {
223 string[] nickArgs = ExtractParameters(message); 297 string[] nickArgs = ExtractParameters(message);
224 string nickname = nickArgs[0]; 298 string nickname = nickArgs[0].Replace(":","");
299 m_nick = nickname;
225 m_hasNick = true; 300 m_hasNick = true;
226 } 301 }
227 302
@@ -243,7 +318,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
243 msg.Sender = this; 318 msg.Sender = this;
244 msg.Channel = 0; 319 msg.Channel = 0;
245 msg.From = this.Name; 320 msg.From = this.Name;
246 msg.Message = privmsgArgs[1]; 321 msg.Message = privmsgArgs[1].Replace(":", "");
247 msg.Position = Vector3.Zero; 322 msg.Position = Vector3.Zero;
248 msg.Scene = m_scene; 323 msg.Scene = m_scene;
249 msg.SenderObject = null; 324 msg.SenderObject = null;
@@ -265,32 +340,45 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
265 340
266 foreach (EntityBase user in users) 341 foreach (EntityBase user in users)
267 { 342 {
268 SendCommand("353 RPL_NAMREPLY \"" + IrcRegionName + " :+" + user.Name.Replace(" ", "")); 343 SendServerCommand("353 " + IrcRegionName + " :+" + user.Name.Replace(" ", ""));
269 } 344 }
270 SendCommand("366 RPL_ENDOFNAMES \"" + IrcRegionName + " :End of /NAMES list\""); 345 SendServerCommand("366 " + IrcRegionName + " :End of /NAMES list");
346 }
347
348 private void IRC_SendWhoReply()
349 {
350 List<EntityBase> users = m_scene.Entities.GetAllByType<ScenePresence>();
351
352 foreach (EntityBase user in users)
353 {
354 //:kubrick.freenode.net 352 toblerone3742 #freenode i=nalioth freenode/staff/ubuntu.member.nalioth irc.freenode.net nalioth G :0 http://www.ubuntu.com/donations
355 //:opensimircd 352 #OpenSim-Test AdamFrisbyIRC nohost.com irc.opensimulator AdamFrisbyIRC H+ :1 Adam FrisbyIRC
356 SendServerCommand("352 " + user.Name.Replace(" ", "") + " " + IrcRegionName + " nohost.com irc.opensimulator " + user.Name.Replace(" ", "") + " H+ " + ":1 " + user.Name);
357 }
358 SendServerCommand("315 " + IrcRegionName + " :End of /WHO list");
271 } 359 }
272 360
273 private void IRC_SendMOTD() 361 private void IRC_SendMOTD()
274 { 362 {
275 SendCommand("375 RPL_MOTDSTART \":- OpenSimulator Message of the day -"); 363 SendServerCommand("375 :- OpenSimulator Message of the day -");
276 SendCommand("372 RPL_MOTD \":- Hiya!"); 364 SendServerCommand("372 :- Hiya!");
277 SendCommand("376 RPL_ENDOFMOTD \":End of /MOTD command\""); 365 SendServerCommand("376 :End of /MOTD command");
278 } 366 }
279 367
280 private void IRC_SendReplyTopic() 368 private void IRC_SendReplyTopic()
281 { 369 {
282 SendCommand("332 RPL_TOPIC \"" + IrcRegionName + " :OpenSimulator IRC Server\""); 370 SendServerCommand("332 " + IrcRegionName + " :OpenSimulator IRC Server");
283 } 371 }
284 372
285 private void IRC_SendReplyUsers() 373 private void IRC_SendReplyUsers()
286 { 374 {
287 List<EntityBase> users = m_scene.Entities.GetAllByType<ScenePresence>(); 375 List<EntityBase> users = m_scene.Entities.GetAllByType<ScenePresence>();
288 376
289 SendCommand("392 RPL_USERSSTART \":UserID Terminal Host\""); 377 SendServerCommand("392 :UserID Terminal Host");
290 378
291 if (users.Count == 0) 379 if (users.Count == 0)
292 { 380 {
293 SendCommand("395 RPL_NOUSERS \":Nobody logged in\""); 381 SendServerCommand("395 :Nobody logged in");
294 return; 382 return;
295 } 383 }
296 384
@@ -309,10 +397,10 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
309 nom[i] = ' '; 397 nom[i] = ' ';
310 } 398 }
311 399
312 SendCommand("393 RPL_USERS \":" + nom + " " + term + " " + host + "\""); 400 SendServerCommand("393 :" + nom + " " + term + " " + host + "");
313 } 401 }
314 402
315 SendCommand("394 RPL_ENDOFUSERS \":End of users\""); 403 SendServerCommand("394 :End of users");
316 } 404 }
317 405
318 private static string ExtractMessage(string buffer) 406 private static string ExtractMessage(string buffer)
@@ -322,7 +410,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
322 if (pos == -1) 410 if (pos == -1)
323 return null; 411 return null;
324 412
325 string command = buffer.Substring(0, pos + 1); 413 string command = buffer.Substring(0, pos + 2);
326 414
327 return command; 415 return command;
328 } 416 }
@@ -331,8 +419,11 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
331 { 419 {
332 string[] msgs = msg.Split(' '); 420 string[] msgs = msg.Split(' ');
333 421
334 if(msgs.Length < 2) 422 if (msgs.Length < 2)
423 {
424 m_log.Warn("[IRCd] Dropped msg: " + msg);
335 return null; 425 return null;
426 }
336 427
337 if (msgs[0].StartsWith(":")) 428 if (msgs[0].StartsWith(":"))
338 return msgs[1]; 429 return msgs[1];
@@ -500,7 +591,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
500 591
501 public uint CircuitCode 592 public uint CircuitCode
502 { 593 {
503 get { return 0; } 594 get { return (uint)Util.RandomClass.Next(0,int.MaxValue); }
504 } 595 }
505 596
506 public event GenericMessage OnGenericMessage; 597 public event GenericMessage OnGenericMessage;
@@ -736,7 +827,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
736 827
737 public void SendRegionHandshake(RegionInfo regionInfo, RegionHandshakeArgs args) 828 public void SendRegionHandshake(RegionInfo regionInfo, RegionHandshakeArgs args)
738 { 829 {
739 m_log.Info("[MXP ClientStack] Completing Handshake to Region"); 830 m_log.Info("[IRCd ClientStack] Completing Handshake to Region");
740 831
741 if (OnRegionHandShakeReply != null) 832 if (OnRegionHandShakeReply != null)
742 { 833 {
@@ -781,7 +872,8 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
781 872
782 public void SendChatMessage(string message, byte type, Vector3 fromPos, string fromName, UUID fromAgentID, byte source, byte audible) 873 public void SendChatMessage(string message, byte type, Vector3 fromPos, string fromName, UUID fromAgentID, byte source, byte audible)
783 { 874 {
784 IRC_SendChannelPrivmsg(fromName, message); 875 if (audible > 0)
876 IRC_SendChannelPrivmsg(fromName, message);
785 } 877 }
786 878
787 private void IRC_SendChannelPrivmsg(string fromName, string message) 879 private void IRC_SendChannelPrivmsg(string fromName, string message)