aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Environment/Modules
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Environment/Modules/ChatModule.cs566
1 files changed, 491 insertions, 75 deletions
diff --git a/OpenSim/Region/Environment/Modules/ChatModule.cs b/OpenSim/Region/Environment/Modules/ChatModule.cs
index d6df978..e07c680 100644
--- a/OpenSim/Region/Environment/Modules/ChatModule.cs
+++ b/OpenSim/Region/Environment/Modules/ChatModule.cs
@@ -52,6 +52,12 @@ namespace OpenSim.Region.Environment.Modules
52 52
53 private IRCChatModule m_irc = null; 53 private IRCChatModule m_irc = null;
54 54
55 private string m_last_new_user = null;
56 private string m_last_leaving_user = null;
57 internal object m_syncInit = new object();
58 internal object m_syncLogout = new object();
59 private Thread m_irc_connector=null;
60
55 public ChatModule() 61 public ChatModule()
56 { 62 {
57 m_log = MainLog.Instance; 63 m_log = MainLog.Instance;
@@ -59,34 +65,48 @@ namespace OpenSim.Region.Environment.Modules
59 65
60 public void Initialise(Scene scene, IConfigSource config) 66 public void Initialise(Scene scene, IConfigSource config)
61 { 67 {
62 // wrap this in a try block so that defaults will work if 68 lock (m_syncInit)
63 // the config file doesn't specify otherwise.
64 try
65 { 69 {
66 m_whisperdistance = config.Configs["Chat"].GetInt("whisper_distance", m_whisperdistance); 70 // wrap this in a try block so that defaults will work if
67 m_saydistance = config.Configs["Chat"].GetInt("say_distance", m_saydistance); 71 // the config file doesn't specify otherwise.
68 m_shoutdistance = config.Configs["Chat"].GetInt("shout_distance", m_shoutdistance); 72 try
69 } 73 {
70 catch (Exception) 74 m_whisperdistance = config.Configs["Chat"].GetInt("whisper_distance", m_whisperdistance);
71 { 75 m_saydistance = config.Configs["Chat"].GetInt("say_distance", m_saydistance);
72 } 76 m_shoutdistance = config.Configs["Chat"].GetInt("shout_distance", m_shoutdistance);
77 }
78 catch (Exception)
79 {
80 }
73 81
74 if (!m_scenes.Contains(scene)) 82 if (!m_scenes.Contains(scene))
75 { 83 {
76 m_scenes.Add(scene); 84 m_scenes.Add(scene);
77 scene.EventManager.OnNewClient += NewClient; 85 scene.EventManager.OnNewClient += NewClient;
78 scene.RegisterModuleInterface<ISimChat>(this); 86 scene.RegisterModuleInterface<ISimChat>(this);
79 } 87 }
88
89 // setup IRC Relay
90 if (m_irc == null) { m_irc = new IRCChatModule(config); }
91 if (m_irc_connector == null) { m_irc_connector = new Thread(IRCConnectRun); }
80 92
81 // setup IRC Relay 93 }
82 m_irc = new IRCChatModule(config);
83 } 94 }
84 95
85 public void PostInitialise() 96 public void PostInitialise()
86 { 97 {
87 if (m_irc.Enabled) 98 if (m_irc.Enabled)
88 { 99 {
89 m_irc.Connect(m_scenes); 100 try
101 {
102 //m_irc.Connect(m_scenes);
103 if (m_irc_connector == null) { m_irc_connector = new Thread(IRCConnectRun); }
104 if (!m_irc_connector.IsAlive) { m_irc_connector.Start(); }
105 }
106 catch (Exception ex)
107 {
108 }
109
90 } 110 }
91 } 111 }
92 112
@@ -107,9 +127,60 @@ namespace OpenSim.Region.Environment.Modules
107 127
108 public void NewClient(IClientAPI client) 128 public void NewClient(IClientAPI client)
109 { 129 {
110 client.OnChatFromViewer += SimChat; 130 try
131 {
132 client.OnChatFromViewer += SimChat;
133
134 if ((m_irc.Enabled) && (m_irc.Connected))
135 {
136 string clientName = client.FirstName + " " + client.LastName;
137 // handles simple case. May not work for hundred connecting in per second.
138 // and the NewClients calles getting interleved
139 // but filters out multiple reports
140 if (clientName != m_last_new_user)
141 {
142 m_last_new_user = clientName;
143 string clientRegion = FindClientRegion(client.FirstName, client.LastName);
144 m_irc.PrivMsg(m_irc.Nick, "Sim", "notices " + clientName + " in "+clientRegion);
145 }
146 }
147 client.OnLogout += ClientLoggedOut;
148 client.OnConnectionClosed += ClientLoggedOut;
149 }
150 catch (Exception ex)
151 {
152 m_log.Error("IRC", "NewClient exception trap:" + ex.ToString());
153 }
111 } 154 }
112 155
156 public void ClientLoggedOut(IClientAPI client)
157 {
158 lock (m_syncLogout)
159 {
160 try
161 {
162 if ((m_irc.Enabled) && (m_irc.Connected))
163 {
164 string clientName = client.FirstName + " " + client.LastName;
165 string clientRegion = FindClientRegion(client.FirstName, client.LastName);
166 // handles simple case. May not work for hundred connecting in per second.
167 // and the NewClients calles getting interleved
168 // but filters out multiple reports
169 if (clientName != m_last_leaving_user)
170 {
171 m_last_leaving_user = clientName;
172 m_irc.PrivMsg(m_irc.Nick, "Sim", "notices " + clientName + " left " + clientRegion);
173 m_log.Verbose("IRC", "IRC watcher notices " + clientName + " left " + clientRegion);
174 }
175 }
176 }
177 catch (Exception ex)
178 {
179 m_log.Error("IRC", "ClientLoggedOut exception trap:" + ex.ToString());
180 }
181 }
182
183 }
113 private void TrySendChatMessage(ScenePresence presence, LLVector3 fromPos, LLVector3 regionPos, 184 private void TrySendChatMessage(ScenePresence presence, LLVector3 fromPos, LLVector3 regionPos,
114 LLUUID fromAgentID, string fromName, ChatTypeEnum type, string message) 185 LLUUID fromAgentID, string fromName, ChatTypeEnum type, string message)
115 { 186 {
@@ -133,6 +204,8 @@ namespace OpenSim.Region.Environment.Modules
133 204
134 public void SimChat(Object sender, ChatFromViewerArgs e) 205 public void SimChat(Object sender, ChatFromViewerArgs e)
135 { 206 {
207 // FROM: Sim TO: IRC
208
136 ScenePresence avatar = null; 209 ScenePresence avatar = null;
137 210
138 //TODO: Move ForEachScenePresence and others into IScene. 211 //TODO: Move ForEachScenePresence and others into IScene.
@@ -163,6 +236,20 @@ namespace OpenSim.Region.Environment.Modules
163 fromAgentID = e.Sender.AgentId; 236 fromAgentID = e.Sender.AgentId;
164 } 237 }
165 238
239 // Try to reconnect to server if not connected
240 if ((m_irc.Enabled)&&(!m_irc.Connected))
241 {
242 // In a non-blocking way. Eventually the connector will get it started
243 try
244 {
245 if (m_irc_connector == null) { m_irc_connector = new Thread(IRCConnectRun); }
246 if (!m_irc_connector.IsAlive) { m_irc_connector.Start(); }
247 }
248 catch (Exception ex)
249 {
250 }
251 }
252
166 if (e.Message.Length > 0) 253 if (e.Message.Length > 0)
167 { 254 {
168 if (m_irc.Connected && (avatar != null)) // this is to keep objects from talking to IRC 255 if (m_irc.Connected && (avatar != null)) // this is to keep objects from talking to IRC
@@ -183,6 +270,40 @@ namespace OpenSim.Region.Environment.Modules
183 } 270 }
184 } 271 }
185 } 272 }
273
274 // if IRC is enabled then just keep trying using a monitor thread
275 public void IRCConnectRun()
276 {
277 while(true)
278 {
279 if ((m_irc.Enabled)&&(!m_irc.Connected))
280 {
281 m_irc.Connect(m_scenes);
282
283 }
284 Thread.Sleep(15000);
285 }
286 }
287
288 public string FindClientRegion(string client_FirstName,string client_LastName)
289 {
290 string sourceRegion = null;
291 foreach (Scene s in m_scenes)
292 {
293 s.ForEachScenePresence(delegate(ScenePresence presence)
294 {
295 if ((presence.IsChildAgent==false)
296 &&(presence.Firstname==client_FirstName)
297 &&(presence.Lastname==client_LastName))
298 {
299 sourceRegion = presence.Scene.RegionInfo.RegionName;
300 //sourceRegion= s.RegionInfo.RegionName;
301 }
302 });
303 if (sourceRegion != null) return sourceRegion;
304 }
305 return "Sim";
306 }
186 } 307 }
187 308
188 internal class IRCChatModule 309 internal class IRCChatModule
@@ -191,6 +312,7 @@ namespace OpenSim.Region.Environment.Modules
191 private uint m_port = 6668; 312 private uint m_port = 6668;
192 private string m_user = "USER OpenSimBot 8 * :I'm a OpenSim to irc bot"; 313 private string m_user = "USER OpenSimBot 8 * :I'm a OpenSim to irc bot";
193 private string m_nick = null; 314 private string m_nick = null;
315 private string m_basenick = null;
194 private string m_channel = null; 316 private string m_channel = null;
195 317
196 private NetworkStream m_stream; 318 private NetworkStream m_stream;
@@ -200,11 +322,13 @@ namespace OpenSim.Region.Environment.Modules
200 322
201 private Thread pingSender; 323 private Thread pingSender;
202 private Thread listener; 324 private Thread listener;
325 internal object m_syncConnect = new object();
203 326
204 private bool m_enabled = false; 327 private bool m_enabled = false;
205 private bool m_connected = false; 328 private bool m_connected = false;
206 329
207 private List<Scene> m_scenes = null; 330 private List<Scene> m_scenes = null;
331 private List<Scene> m_last_scenes = null;
208 private LogBase m_log; 332 private LogBase m_log;
209 333
210 public IRCChatModule(IConfigSource config) 334 public IRCChatModule(IConfigSource config)
@@ -214,15 +338,32 @@ namespace OpenSim.Region.Environment.Modules
214 m_writer = null; 338 m_writer = null;
215 m_reader = null; 339 m_reader = null;
216 340
341 // configuration in OpenSim.ini
342 // [IRC]
343 // server = chat.freenode.net
344 // nick = OSimBot_mysim
345 // ;username = USER OpenSimBot 8 * :I'm a OpenSim to irc bot
346 // ; username is the IRC command line sent
347 // ; USER <irc_user> <visible=8,invisible=0> * : <IRC_realname>
348 // channel = #opensim-regions
349 // port = 6667
350 //
351 // Traps I/O disconnects so it does not crash the sim
352 // Trys to reconnect if disconnected and someone says something
353 // Tells IRC server "QUIT" when doing a close (just to be nice)
354 // Default port back to 6667
355
217 try 356 try
218 { 357 {
219 m_server = config.Configs["IRC"].GetString("server"); 358 m_server = config.Configs["IRC"].GetString("server");
220 m_nick = config.Configs["IRC"].GetString("nick"); 359 m_nick = config.Configs["IRC"].GetString("nick");
360 m_basenick = m_nick;
221 m_channel = config.Configs["IRC"].GetString("channel"); 361 m_channel = config.Configs["IRC"].GetString("channel");
222 m_port = (uint) config.Configs["IRC"].GetInt("port", (int) m_port); 362 m_port = (uint) config.Configs["IRC"].GetInt("port", (int) m_port);
223 m_user = config.Configs["IRC"].GetString("username", m_user); 363 m_user = config.Configs["IRC"].GetString("username", m_user);
224 if (m_server != null && m_nick != null && m_channel != null) 364 if (m_server != null && m_nick != null && m_channel != null)
225 { 365 {
366 m_nick = m_nick + Util.RandomClass.Next(1, 99);
226 m_enabled = true; 367 m_enabled = true;
227 } 368 }
228 } 369 }
@@ -235,37 +376,42 @@ namespace OpenSim.Region.Environment.Modules
235 376
236 public bool Connect(List<Scene> scenes) 377 public bool Connect(List<Scene> scenes)
237 { 378 {
238 try 379 lock (m_syncConnect)
239 {
240 m_scenes = scenes;
241
242 m_tcp = new TcpClient(m_server, (int) m_port);
243 m_log.Verbose("IRC", "Connecting...");
244 m_stream = m_tcp.GetStream();
245 m_log.Verbose("IRC", "Connected to " + m_server);
246 m_reader = new StreamReader(m_stream);
247 m_writer = new StreamWriter(m_stream);
248
249 pingSender = new Thread(new ThreadStart(PingRun));
250 pingSender.Start();
251
252 listener = new Thread(new ThreadStart(ListenerRun));
253 listener.Start();
254
255 m_writer.WriteLine(m_user);
256 m_writer.Flush();
257 m_writer.WriteLine("NICK " + m_nick);
258 m_writer.Flush();
259 m_writer.WriteLine("JOIN " + m_channel);
260 m_writer.Flush();
261 m_log.Verbose("IRC", "Connection fully established");
262 m_connected = true;
263 }
264 catch (Exception e)
265 { 380 {
266 Console.WriteLine(e.ToString()); 381 try
382 {
383 if (m_connected) return true;
384 m_scenes = scenes;
385 if (m_last_scenes == null) { m_last_scenes = scenes; }
386
387 m_tcp = new TcpClient(m_server, (int)m_port);
388 m_log.Verbose("IRC", "Connecting...");
389 m_stream = m_tcp.GetStream();
390 m_log.Verbose("IRC", "Connected to " + m_server);
391 m_reader = new StreamReader(m_stream);
392 m_writer = new StreamWriter(m_stream);
393
394 pingSender = new Thread(new ThreadStart(PingRun));
395 pingSender.Start();
396
397 listener = new Thread(new ThreadStart(ListenerRun));
398 listener.Start();
399
400 m_writer.WriteLine(m_user);
401 m_writer.Flush();
402 m_writer.WriteLine("NICK " + m_nick);
403 m_writer.Flush();
404 m_writer.WriteLine("JOIN " + m_channel);
405 m_writer.Flush();
406 m_log.Verbose("IRC", "Connection fully established");
407 m_connected = true;
408 }
409 catch (Exception e)
410 {
411 Console.WriteLine(e.ToString());
412 }
413 return m_connected;
267 } 414 }
268 return m_connected;
269 } 415 }
270 416
271 public bool Enabled 417 public bool Enabled
@@ -278,26 +424,53 @@ namespace OpenSim.Region.Environment.Modules
278 get { return m_connected; } 424 get { return m_connected; }
279 } 425 }
280 426
427 public string Nick
428 {
429 get { return m_nick; }
430 }
431
432 public void Reconnect()
433 {
434 m_connected = false;
435 listener.Abort();
436 pingSender.Abort();
437 m_writer.Close();
438 m_reader.Close();
439 m_tcp.Close();
440 if (m_enabled) { Connect(m_last_scenes); }
441
442 }
443
281 public void PrivMsg(string from, string region, string msg) 444 public void PrivMsg(string from, string region, string msg)
282 { 445 {
446 // One message to the IRC server
447
283 try 448 try
284 { 449 {
285 m_writer.WriteLine("PRIVMSG {0} :<{1} in {2}>: {3}", m_channel, from, region, msg); 450 m_writer.WriteLine("PRIVMSG {0} :<{1} in {2}>: {3}", m_channel, from, region, msg);
286 m_writer.Flush(); 451 m_writer.Flush();
452 m_log.Verbose("IRC", "PrivMsg " + from + " in " + region + " :" + msg);
287 } 453 }
288 catch (IOException) 454 catch (IOException)
289 { 455 {
290 m_log.Error("IRC", "Disconnected from IRC server."); 456 m_log.Error("IRC", "Disconnected from IRC server.(PrivMsg)");
291 listener.Abort(); 457 Reconnect();
292 pingSender.Abort(); 458 }
293 m_connected = false; 459 catch (Exception ex)
460 {
461 m_log.Error("IRC", "PrivMsg exception trap:" + ex.ToString());
294 } 462 }
295 } 463 }
296 464
297 private Dictionary<string, string> ExtractMsg(string input) 465 private Dictionary<string, string> ExtractMsg(string input)
298 { 466 {
467 //examines IRC commands and extracts any private messages
468 // which will then be reboadcast in the Sim
469
470 m_log.Verbose("IRC", "ExtractMsg: " + input);
299 Dictionary<string, string> result = null; 471 Dictionary<string, string> result = null;
300 string regex = @":(?<nick>\w*)!~(?<user>\S*) PRIVMSG (?<channel>\S+) :(?<msg>.*)"; 472 //string regex = @":(?<nick>\w*)!~(?<user>\S*) PRIVMSG (?<channel>\S+) :(?<msg>.*)";
473 string regex = @":(?<nick>\w*)!(?<user>\S*) PRIVMSG (?<channel>\S+) :(?<msg>.*)";
301 Regex RE = new Regex(regex, RegexOptions.Multiline); 474 Regex RE = new Regex(regex, RegexOptions.Multiline);
302 MatchCollection matches = RE.Matches(input); 475 MatchCollection matches = RE.Matches(input);
303 // Get some direct matches $1 $4 is a 476 // Get some direct matches $1 $4 is a
@@ -322,11 +495,28 @@ namespace OpenSim.Region.Environment.Modules
322 495
323 public void PingRun() 496 public void PingRun()
324 { 497 {
325 while (true) 498 // IRC keep alive thread
499 // send PING ever 15 seconds
500 while (true)
326 { 501 {
327 m_writer.WriteLine("PING :" + m_server); 502 try
328 m_writer.Flush(); 503 {
329 Thread.Sleep(15000); 504 if (m_connected == true)
505 {
506 m_writer.WriteLine("PING :" + m_server);
507 m_writer.Flush();
508 Thread.Sleep(15000);
509 }
510 }
511 catch (IOException)
512 {
513 m_log.Error("IRC", "Disconnected from IRC server.(PingRun)");
514 Reconnect();
515 }
516 catch (Exception ex)
517 {
518 m_log.Error("IRC", "PingRun exception trap:" + ex.ToString());
519 }
330 } 520 }
331 } 521 }
332 522
@@ -336,36 +526,262 @@ namespace OpenSim.Region.Environment.Modules
336 LLVector3 pos = new LLVector3(128, 128, 20); 526 LLVector3 pos = new LLVector3(128, 128, 20);
337 while (true) 527 while (true)
338 { 528 {
339 while ((inputLine = m_reader.ReadLine()) != null) 529 while ((m_connected == true) && ((inputLine = m_reader.ReadLine()) != null))
340 { 530 {
341 // Console.WriteLine(inputLine); 531 try
342 if (inputLine.Contains(m_channel))
343 { 532 {
344 Dictionary<string, string> data = ExtractMsg(inputLine); 533 // Console.WriteLine(inputLine);
345 if (data != null) 534 if (inputLine.Contains(m_channel))
346 { 535 {
347 foreach (Scene m_scene in m_scenes) 536 Dictionary<string, string> data = ExtractMsg(inputLine);
537 // Any chat ???
538 if (data != null)
348 { 539 {
349 m_scene.ForEachScenePresence(delegate(ScenePresence avatar) 540 foreach (Scene m_scene in m_scenes)
350 { 541 {
351 if (!avatar.IsChildAgent) 542 m_scene.ForEachScenePresence(delegate(ScenePresence avatar)
352 { 543 {
353 avatar.ControllingClient.SendChatMessage( 544 if (!avatar.IsChildAgent)
354 Helpers.StringToField(data["msg"]), 255, 545 {
355 pos, data["nick"], 546 avatar.ControllingClient.SendChatMessage(
356 LLUUID.Zero); 547 Helpers.StringToField(data["msg"]), 255,
357 } 548 pos, data["nick"],
358 }); 549 LLUUID.Zero);
550 }
551 });
552 }
553
554
359 } 555 }
556 else
557 {
558 // Was an command from the IRC server
559 ProcessIRCCommand(inputLine);
560 }
561 }
562 else
563 {
564 // Was an command from the IRC server
565 ProcessIRCCommand(inputLine);
360 } 566 }
567 Thread.Sleep(150);
568 }
569 catch (IOException)
570 {
571 m_log.Error("IRC", "ListenerRun IOException. Disconnected from IRC server ??? (ListenerRun)");
572 Reconnect();
573 }
574 catch (Exception ex)
575 {
576 m_log.Error("IRC", "ListenerRun exception trap:" + ex.ToString());
361 } 577 }
362 } 578 }
363 Thread.Sleep(50);
364 } 579 }
365 } 580 }
366 581
582 public void BroadcastSim(string message,string sender)
583 {
584 LLVector3 pos = new LLVector3(128, 128, 20);
585 try
586 {
587 foreach (Scene m_scene in m_scenes)
588 {
589 m_scene.ForEachScenePresence(delegate(ScenePresence avatar)
590 {
591 if (!avatar.IsChildAgent)
592 {
593 avatar.ControllingClient.SendChatMessage(
594 Helpers.StringToField(message), 255,
595 pos, sender,
596 LLUUID.Zero);
597 }
598 });
599 }
600 }
601 catch (Exception ex) // IRC gate should not crash Sim
602 {
603 m_log.Error("IRC", "BroadcastSim Exception Trap:" + ex.ToString());
604
605 }
606
607
608 }
609 public enum ErrorReplies
610 {
611 NotRegistered = 451, // ":You have not registered"
612 NicknameInUse = 433 // "<nick> :Nickname is already in use"
613 }
614 public enum Replies
615 {
616 MotdStart = 375, // ":- <server> Message of the day - "
617 Motd = 372, // ":- <text>"
618 EndOfMotd = 376 // ":End of /MOTD command"
619
620 }
621 public void ProcessIRCCommand(string command)
622 {
623 //m_log.Verbose("IRC", "ProcessIRCCommand:"+command);
624
625 string[] commArgs = new string[command.Split(' ').Length];
626 string c_server = m_server;
627
628 commArgs = command.Split(' ');
629 if (commArgs[0].Substring(0, 1) == ":")
630 {
631 commArgs[0] = commArgs[0].Remove(0, 1);
632 }
633 if (commArgs[1] == "002")
634 {
635 // fetch the correct servername
636 // ex: irc.freenode.net -> brown.freenode.net/kornbluth.freenode.net/...
637 // irc.bluewin.ch -> irc1.bluewin.ch/irc2.bluewin.ch
638
639 c_server = (commArgs[6].Split('['))[0];
640 m_server = c_server;
641 }
642
643 if (commArgs[0] == "ERROR")
644 {
645 m_log.Error("IRC", "IRC SERVER ERROR:" + command);
646 }
647
648 if (commArgs[0] == "PING")
649 {
650 string p_reply = "";
651
652 for (int i = 1; i < commArgs.Length; i++)
653 {
654 p_reply += commArgs[i] + " ";
655 }
656
657 m_writer.WriteLine("PONG " + p_reply);
658 m_writer.Flush();
659
660 }
661 else if (commArgs[0] == c_server)
662 {
663 // server message
664 try
665 {
666 Int32 commandCode = Int32.Parse(commArgs[1]);
667 switch (commandCode)
668 {
669 case (int)ErrorReplies.NicknameInUse:
670 // Gen a new name
671 m_nick = m_basenick + Util.RandomClass.Next(1, 99);
672 m_log.Error("IRC", "IRC SERVER reports NicknameInUse, trying " + m_nick);
673 // Retry
674 m_writer.WriteLine("NICK " + m_nick);
675 m_writer.Flush();
676 m_writer.WriteLine("JOIN " + m_channel);
677 m_writer.Flush();
678 break;
679 case (int)ErrorReplies.NotRegistered:
680 break;
681 case (int)Replies.EndOfMotd:
682 break;
683 }
684 }
685 catch (Exception ex)
686 {
687 }
688
689 }
690 else
691 {
692 // Normal message
693 string commAct = commArgs[1];
694 switch (commAct)
695 {
696 case "JOIN": eventIrcJoin(commArgs); break;
697 case "PART": eventIrcPart(commArgs); break;
698 case "MODE": eventIrcMode(commArgs); break;
699 case "NICK": eventIrcNickChange(commArgs); break;
700 case "KICK": eventIrcKick(commArgs); break;
701 case "QUIT": eventIrcQuit(commArgs); break;
702 case "PONG": break; // that's nice
703 }
704
705
706 }
707 }
708
709 public void eventIrcJoin(string[] commArgs)
710 {
711 string IrcChannel = commArgs[2];
712 string IrcUser = commArgs[0].Split('!')[0];
713 BroadcastSim(IrcUser + " is joining " + IrcChannel, m_nick);
714
715 }
716
717 public void eventIrcPart(string[] commArgs)
718 {
719 string IrcChannel = commArgs[2];
720 string IrcUser = commArgs[0].Split('!')[0];
721 BroadcastSim(IrcUser + " is parting " + IrcChannel, m_nick);
722
723 }
724 public void eventIrcMode(string[] commArgs)
725 {
726 string IrcChannel = commArgs[2];
727 string IrcUser = commArgs[0].Split('!')[0];
728 string UserMode = "";
729 for (int i = 3; i < commArgs.Length; i++)
730 {
731 UserMode += commArgs[i] + " ";
732 }
733
734 if (UserMode.Substring(0, 1) == ":")
735 {
736 UserMode = UserMode.Remove(0, 1);
737 }
738
739 }
740 public void eventIrcNickChange(string[] commArgs)
741 {
742 string UserOldNick = commArgs[0].Split('!')[0];
743 string UserNewNick = commArgs[2].Remove(0, 1);
744 BroadcastSim(UserOldNick + " changed their nick to " + UserNewNick, m_nick);
745
746 }
747
748 public void eventIrcKick(string[] commArgs)
749 {
750 string UserKicker = commArgs[0].Split('!')[0];
751 string UserKicked = commArgs[3];
752 string IrcChannel = commArgs[2];
753 string KickMessage = "";
754 for (int i = 4; i < commArgs.Length; i++)
755 {
756 KickMessage += commArgs[i] + " ";
757 }
758 BroadcastSim(UserKicker + " kicked " + UserKicked +" on "+IrcChannel+" saying "+KickMessage, m_nick);
759 if (UserKicked == m_nick)
760 {
761 BroadcastSim("Hey, that was me!!!", m_nick);
762
763 }
764 }
765
766 public void eventIrcQuit(string[] commArgs)
767 {
768 string IrcUser = commArgs[0].Split('!')[0];
769 string QuitMessage = "";
770
771 for (int i = 2; i < commArgs.Length; i++)
772 {
773 QuitMessage += commArgs[i] + " ";
774 }
775 BroadcastSim(IrcUser + " quits saying " + QuitMessage, m_nick);
776
777 }
778
779
367 public void Close() 780 public void Close()
368 { 781 {
782 m_connected = false;
783 m_writer.WriteLine("QUIT :" + m_nick + " to " + m_channel + " wormhole with " + m_server + " closing");
784 m_writer.Flush();
369 listener.Abort(); 785 listener.Abort();
370 pingSender.Abort(); 786 pingSender.Abort();
371 m_writer.Close(); 787 m_writer.Close();
@@ -373,4 +789,4 @@ namespace OpenSim.Region.Environment.Modules
373 m_tcp.Close(); 789 m_tcp.Close();
374 } 790 }
375 } 791 }
376} \ No newline at end of file 792}