aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Environment/Modules/Avatar/Chat/ChatModule.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Environment/Modules/Avatar/Chat/ChatModule.cs')
-rw-r--r--OpenSim/Region/Environment/Modules/Avatar/Chat/ChatModule.cs349
1 files changed, 193 insertions, 156 deletions
diff --git a/OpenSim/Region/Environment/Modules/Avatar/Chat/ChatModule.cs b/OpenSim/Region/Environment/Modules/Avatar/Chat/ChatModule.cs
index 1281873..966f5f3 100644
--- a/OpenSim/Region/Environment/Modules/Avatar/Chat/ChatModule.cs
+++ b/OpenSim/Region/Environment/Modules/Avatar/Chat/ChatModule.cs
@@ -44,21 +44,21 @@ namespace OpenSim.Region.Environment.Modules.Avatar.Chat
44 public class ChatModule : IRegionModule, ISimChat 44 public class ChatModule : IRegionModule, ISimChat
45 { 45 {
46 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 46 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
47 47 private string m_defaultzone = null;
48 private List<Scene> m_scenes = new List<Scene>();
49
50 private int m_whisperdistance = 10;
51 private int m_saydistance = 30;
52 private int m_shoutdistance = 100;
53 48
54 private IRCChatModule m_irc = null; 49 private IRCChatModule m_irc = null;
50 private Thread m_irc_connector = null;
55 51
56 private string m_last_new_user = null;
57 private string m_last_leaving_user = null; 52 private string m_last_leaving_user = null;
58 private string m_defaultzone = null; 53 private string m_last_new_user = null;
54 private int m_saydistance = 30;
55 private List<Scene> m_scenes = new List<Scene>();
56 private int m_shoutdistance = 100;
59 internal object m_syncInit = new object(); 57 internal object m_syncInit = new object();
60 internal object m_syncLogout = new object(); 58 internal object m_syncLogout = new object();
61 private Thread m_irc_connector=null; 59 private int m_whisperdistance = 10;
60
61 #region IRegionModule Members
62 62
63 public void Initialise(Scene scene, IConfigSource config) 63 public void Initialise(Scene scene, IConfigSource config)
64 { 64 {
@@ -85,14 +85,17 @@ namespace OpenSim.Region.Environment.Modules.Avatar.Chat
85 85
86 try 86 try
87 { 87 {
88 m_defaultzone = config.Configs["IRC"].GetString("nick","Sim"); 88 m_defaultzone = config.Configs["IRC"].GetString("nick", "Sim");
89 } 89 }
90 catch (Exception) 90 catch (Exception)
91 { 91 {
92 } 92 }
93 93
94 // setup IRC Relay 94 // setup IRC Relay
95 if (m_irc == null) { m_irc = new IRCChatModule(config); } 95 if (m_irc == null)
96 {
97 m_irc = new IRCChatModule(config);
98 }
96 if (m_irc_connector == null) 99 if (m_irc_connector == null)
97 { 100 {
98 m_irc_connector = new Thread(IRCConnectRun); 101 m_irc_connector = new Thread(IRCConnectRun);
@@ -142,83 +145,9 @@ namespace OpenSim.Region.Environment.Modules.Avatar.Chat
142 get { return true; } 145 get { return true; }
143 } 146 }
144 147
145 public void NewClient(IClientAPI client) 148 #endregion
146 {
147 try
148 {
149 client.OnChatFromViewer += SimChat;
150 149
151 if ((m_irc.Enabled) && (m_irc.Connected)) 150 #region ISimChat Members
152 {
153 string clientName = client.FirstName + " " + client.LastName;
154 // handles simple case. May not work for hundred connecting in per second.
155 // and the NewClients calles getting interleved
156 // but filters out multiple reports
157 if (clientName != m_last_new_user)
158 {
159 m_last_new_user = clientName;
160 string clientRegion = FindClientRegion(client.FirstName, client.LastName);
161 m_irc.PrivMsg(m_irc.Nick, "Sim", "notices " + clientName + " in "+clientRegion);
162 }
163 }
164 client.OnLogout += ClientLoggedOut;
165 client.OnConnectionClosed += ClientLoggedOut;
166 client.OnLogout += ClientLoggedOut;
167 }
168 catch (Exception ex)
169 {
170 m_log.Error("[IRC]: NewClient exception trap:" + ex.ToString());
171 }
172 }
173
174 public void ClientLoggedOut(IClientAPI client)
175 {
176 lock (m_syncLogout)
177 {
178 try
179 {
180 if ((m_irc.Enabled) && (m_irc.Connected))
181 {
182 string clientName = client.FirstName + " " + client.LastName;
183 string clientRegion = FindClientRegion(client.FirstName, client.LastName);
184 // handles simple case. May not work for hundred connecting in per second.
185 // and the NewClients calles getting interleved
186 // but filters out multiple reports
187 if (clientName != m_last_leaving_user)
188 {
189 m_last_leaving_user = clientName;
190 m_irc.PrivMsg(m_irc.Nick, "Sim", "notices " + clientName + " left " + clientRegion);
191 m_log.Info("[IRC]: IRC watcher notices " + clientName + " left " + clientRegion);
192 }
193 }
194 }
195 catch (Exception ex)
196 {
197 m_log.Error("[IRC]: ClientLoggedOut exception trap:" + ex.ToString());
198 }
199 }
200 }
201
202 private void TrySendChatMessage(ScenePresence presence, LLVector3 fromPos, LLVector3 regionPos,
203 LLUUID fromAgentID, string fromName, ChatTypeEnum type, string message)
204 {
205 if (!presence.IsChildAgent)
206 {
207 LLVector3 fromRegionPos = fromPos + regionPos;
208 LLVector3 toRegionPos = presence.AbsolutePosition + regionPos;
209 int dis = Math.Abs((int) Util.GetDistanceTo(toRegionPos, fromRegionPos));
210
211 if (type == ChatTypeEnum.Whisper && dis > m_whisperdistance ||
212 type == ChatTypeEnum.Say && dis > m_saydistance ||
213 type == ChatTypeEnum.Shout && dis > m_shoutdistance)
214 {
215 return;
216 }
217
218 // TODO: should change so the message is sent through the avatar rather than direct to the ClientView
219 presence.ControllingClient.SendChatMessage(message, (byte) type, fromPos, fromName, fromAgentID);
220 }
221 }
222 151
223 public void SimChat(Object sender, ChatFromViewerArgs e) 152 public void SimChat(Object sender, ChatFromViewerArgs e)
224 { 153 {
@@ -289,7 +218,7 @@ namespace OpenSim.Region.Environment.Modules.Avatar.Chat
289 m_irc.PrivMsg(fromName, scene.RegionInfo.RegionName, e.Message); 218 m_irc.PrivMsg(fromName, scene.RegionInfo.RegionName, e.Message);
290 } 219 }
291 } 220 }
292 221
293 foreach (Scene s in m_scenes) 222 foreach (Scene s in m_scenes)
294 { 223 {
295 s.ForEachScenePresence(delegate(ScenePresence presence) 224 s.ForEachScenePresence(delegate(ScenePresence presence)
@@ -301,12 +230,92 @@ namespace OpenSim.Region.Environment.Modules.Avatar.Chat
301 } 230 }
302 } 231 }
303 232
233 #endregion
234
235 public void NewClient(IClientAPI client)
236 {
237 try
238 {
239 client.OnChatFromViewer += SimChat;
240
241 if ((m_irc.Enabled) && (m_irc.Connected))
242 {
243 string clientName = client.FirstName + " " + client.LastName;
244 // handles simple case. May not work for hundred connecting in per second.
245 // and the NewClients calles getting interleved
246 // but filters out multiple reports
247 if (clientName != m_last_new_user)
248 {
249 m_last_new_user = clientName;
250 string clientRegion = FindClientRegion(client.FirstName, client.LastName);
251 m_irc.PrivMsg(m_irc.Nick, "Sim", "notices " + clientName + " in " + clientRegion);
252 }
253 }
254 client.OnLogout += ClientLoggedOut;
255 client.OnConnectionClosed += ClientLoggedOut;
256 client.OnLogout += ClientLoggedOut;
257 }
258 catch (Exception ex)
259 {
260 m_log.Error("[IRC]: NewClient exception trap:" + ex.ToString());
261 }
262 }
263
264 public void ClientLoggedOut(IClientAPI client)
265 {
266 lock (m_syncLogout)
267 {
268 try
269 {
270 if ((m_irc.Enabled) && (m_irc.Connected))
271 {
272 string clientName = client.FirstName + " " + client.LastName;
273 string clientRegion = FindClientRegion(client.FirstName, client.LastName);
274 // handles simple case. May not work for hundred connecting in per second.
275 // and the NewClients calles getting interleved
276 // but filters out multiple reports
277 if (clientName != m_last_leaving_user)
278 {
279 m_last_leaving_user = clientName;
280 m_irc.PrivMsg(m_irc.Nick, "Sim", "notices " + clientName + " left " + clientRegion);
281 m_log.Info("[IRC]: IRC watcher notices " + clientName + " left " + clientRegion);
282 }
283 }
284 }
285 catch (Exception ex)
286 {
287 m_log.Error("[IRC]: ClientLoggedOut exception trap:" + ex.ToString());
288 }
289 }
290 }
291
292 private void TrySendChatMessage(ScenePresence presence, LLVector3 fromPos, LLVector3 regionPos,
293 LLUUID fromAgentID, string fromName, ChatTypeEnum type, string message)
294 {
295 if (!presence.IsChildAgent)
296 {
297 LLVector3 fromRegionPos = fromPos + regionPos;
298 LLVector3 toRegionPos = presence.AbsolutePosition + regionPos;
299 int dis = Math.Abs((int) Util.GetDistanceTo(toRegionPos, fromRegionPos));
300
301 if (type == ChatTypeEnum.Whisper && dis > m_whisperdistance ||
302 type == ChatTypeEnum.Say && dis > m_saydistance ||
303 type == ChatTypeEnum.Shout && dis > m_shoutdistance)
304 {
305 return;
306 }
307
308 // TODO: should change so the message is sent through the avatar rather than direct to the ClientView
309 presence.ControllingClient.SendChatMessage(message, (byte) type, fromPos, fromName, fromAgentID);
310 }
311 }
312
304 // if IRC is enabled then just keep trying using a monitor thread 313 // if IRC is enabled then just keep trying using a monitor thread
305 public void IRCConnectRun() 314 public void IRCConnectRun()
306 { 315 {
307 while(true) 316 while (true)
308 { 317 {
309 if ((m_irc.Enabled)&&(!m_irc.Connected)) 318 if ((m_irc.Enabled) && (!m_irc.Connected))
310 { 319 {
311 m_irc.Connect(m_scenes); 320 m_irc.Connect(m_scenes);
312 } 321 }
@@ -314,54 +323,76 @@ namespace OpenSim.Region.Environment.Modules.Avatar.Chat
314 } 323 }
315 } 324 }
316 325
317 public string FindClientRegion(string client_FirstName,string client_LastName) 326 public string FindClientRegion(string client_FirstName, string client_LastName)
318 { 327 {
319 string sourceRegion = null; 328 string sourceRegion = null;
320 foreach (Scene s in m_scenes) 329 foreach (Scene s in m_scenes)
321 { 330 {
322 s.ForEachScenePresence(delegate(ScenePresence presence) 331 s.ForEachScenePresence(delegate(ScenePresence presence)
323 { 332 {
324 if ((presence.IsChildAgent==false) 333 if ((presence.IsChildAgent == false)
325 &&(presence.Firstname==client_FirstName) 334 && (presence.Firstname == client_FirstName)
326 &&(presence.Lastname==client_LastName)) 335 && (presence.Lastname == client_LastName))
327 { 336 {
328 sourceRegion = presence.Scene.RegionInfo.RegionName; 337 sourceRegion = presence.Scene.RegionInfo.RegionName;
329 //sourceRegion= s.RegionInfo.RegionName; 338 //sourceRegion= s.RegionInfo.RegionName;
330 } 339 }
331 }); 340 });
332 if (sourceRegion != null) return sourceRegion; 341 if (sourceRegion != null) return sourceRegion;
342 }
343 if (m_defaultzone == null)
344 {
345 m_defaultzone = "Sim";
333 } 346 }
334 if (m_defaultzone == null) { m_defaultzone = "Sim"; }
335 return m_defaultzone; 347 return m_defaultzone;
336 } 348 }
337 } 349 }
338 350
339 internal class IRCChatModule 351 internal class IRCChatModule
340 { 352 {
353 #region ErrorReplies enum
354
355 public enum ErrorReplies
356 {
357 NotRegistered = 451, // ":You have not registered"
358 NicknameInUse = 433 // "<nick> :Nickname is already in use"
359 }
360
361 #endregion
362
363 #region Replies enum
364
365 public enum Replies
366 {
367 MotdStart = 375, // ":- <server> Message of the day - "
368 Motd = 372, // ":- <text>"
369 EndOfMotd = 376 // ":End of /MOTD command"
370 }
371
372 #endregion
373
341 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 374 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
375 private Thread listener;
342 376
343 private string m_server = null;
344 private uint m_port = 6668;
345 private string m_user = "USER OpenSimBot 8 * :I'm a OpenSim to irc bot";
346 private string m_nick = null;
347 private string m_basenick = null; 377 private string m_basenick = null;
348 private string m_channel = null; 378 private string m_channel = null;
379 private bool m_connected = false;
380 private bool m_enabled = false;
381 private List<Scene> m_last_scenes = null;
382 private string m_nick = null;
383 private uint m_port = 6668;
349 private string m_privmsgformat = "PRIVMSG {0} :<{1} in {2}>: {3}"; 384 private string m_privmsgformat = "PRIVMSG {0} :<{1} in {2}>: {3}";
385 private StreamReader m_reader;
386 private List<Scene> m_scenes = null;
387 private string m_server = null;
350 388
351 private NetworkStream m_stream; 389 private NetworkStream m_stream;
390 internal object m_syncConnect = new object();
352 private TcpClient m_tcp; 391 private TcpClient m_tcp;
392 private string m_user = "USER OpenSimBot 8 * :I'm a OpenSim to irc bot";
353 private StreamWriter m_writer; 393 private StreamWriter m_writer;
354 private StreamReader m_reader;
355 394
356 private Thread pingSender; 395 private Thread pingSender;
357 private Thread listener;
358 internal object m_syncConnect = new object();
359
360 private bool m_enabled = false;
361 private bool m_connected = false;
362
363 private List<Scene> m_scenes = null;
364 private List<Scene> m_last_scenes = null;
365 396
366 public IRCChatModule(IConfigSource config) 397 public IRCChatModule(IConfigSource config)
367 { 398 {
@@ -412,6 +443,21 @@ namespace OpenSim.Region.Environment.Modules.Avatar.Chat
412 } 443 }
413 } 444 }
414 445
446 public bool Enabled
447 {
448 get { return m_enabled; }
449 }
450
451 public bool Connected
452 {
453 get { return m_connected; }
454 }
455
456 public string Nick
457 {
458 get { return m_nick; }
459 }
460
415 public bool Connect(List<Scene> scenes) 461 public bool Connect(List<Scene> scenes)
416 { 462 {
417 lock (m_syncConnect) 463 lock (m_syncConnect)
@@ -420,9 +466,12 @@ namespace OpenSim.Region.Environment.Modules.Avatar.Chat
420 { 466 {
421 if (m_connected) return true; 467 if (m_connected) return true;
422 m_scenes = scenes; 468 m_scenes = scenes;
423 if (m_last_scenes == null) { m_last_scenes = scenes; } 469 if (m_last_scenes == null)
470 {
471 m_last_scenes = scenes;
472 }
424 473
425 m_tcp = new TcpClient(m_server, (int)m_port); 474 m_tcp = new TcpClient(m_server, (int) m_port);
426 m_log.Info("[IRC]: Connecting..."); 475 m_log.Info("[IRC]: Connecting...");
427 m_stream = m_tcp.GetStream(); 476 m_stream = m_tcp.GetStream();
428 m_log.Info("[IRC]: Connected to " + m_server); 477 m_log.Info("[IRC]: Connected to " + m_server);
@@ -458,21 +507,6 @@ namespace OpenSim.Region.Environment.Modules.Avatar.Chat
458 } 507 }
459 } 508 }
460 509
461 public bool Enabled
462 {
463 get { return m_enabled; }
464 }
465
466 public bool Connected
467 {
468 get { return m_connected; }
469 }
470
471 public string Nick
472 {
473 get { return m_nick; }
474 }
475
476 public void Reconnect() 510 public void Reconnect()
477 { 511 {
478 m_connected = false; 512 m_connected = false;
@@ -481,7 +515,10 @@ namespace OpenSim.Region.Environment.Modules.Avatar.Chat
481 m_writer.Close(); 515 m_writer.Close();
482 m_reader.Close(); 516 m_reader.Close();
483 m_tcp.Close(); 517 m_tcp.Close();
484 if (m_enabled) { Connect(m_last_scenes); } 518 if (m_enabled)
519 {
520 Connect(m_last_scenes);
521 }
485 } 522 }
486 523
487 public void PrivMsg(string from, string region, string msg) 524 public void PrivMsg(string from, string region, string msg)
@@ -627,7 +664,7 @@ namespace OpenSim.Region.Environment.Modules.Avatar.Chat
627 } 664 }
628 } 665 }
629 666
630 public void BroadcastSim(string message,string sender) 667 public void BroadcastSim(string message, string sender)
631 { 668 {
632 LLVector3 pos = new LLVector3(128, 128, 20); 669 LLVector3 pos = new LLVector3(128, 128, 20);
633 try 670 try
@@ -652,23 +689,10 @@ namespace OpenSim.Region.Environment.Modules.Avatar.Chat
652 } 689 }
653 } 690 }
654 691
655 public enum ErrorReplies
656 {
657 NotRegistered = 451, // ":You have not registered"
658 NicknameInUse = 433 // "<nick> :Nickname is already in use"
659 }
660
661 public enum Replies
662 {
663 MotdStart = 375, // ":- <server> Message of the day - "
664 Motd = 372, // ":- <text>"
665 EndOfMotd = 376 // ":End of /MOTD command"
666 }
667
668 public void ProcessIRCCommand(string command) 692 public void ProcessIRCCommand(string command)
669 { 693 {
670 //m_log.Info("[IRC]: ProcessIRCCommand:" + command); 694 //m_log.Info("[IRC]: ProcessIRCCommand:" + command);
671 695
672 string[] commArgs = new string[command.Split(' ').Length]; 696 string[] commArgs = new string[command.Split(' ').Length];
673 string c_server = m_server; 697 string c_server = m_server;
674 698
@@ -690,7 +714,7 @@ namespace OpenSim.Region.Environment.Modules.Avatar.Chat
690 714
691 if (commArgs[0] == "ERROR") 715 if (commArgs[0] == "ERROR")
692 { 716 {
693 m_log.Error("[IRC]: IRC SERVER ERROR:" + command); 717 m_log.Error("[IRC]: IRC SERVER ERROR:" + command);
694 } 718 }
695 719
696 if (commArgs[0] == "PING") 720 if (commArgs[0] == "PING")
@@ -713,7 +737,7 @@ namespace OpenSim.Region.Environment.Modules.Avatar.Chat
713 Int32 commandCode = Int32.Parse(commArgs[1]); 737 Int32 commandCode = Int32.Parse(commArgs[1]);
714 switch (commandCode) 738 switch (commandCode)
715 { 739 {
716 case (int)ErrorReplies.NicknameInUse: 740 case (int) ErrorReplies.NicknameInUse:
717 // Gen a new name 741 // Gen a new name
718 m_nick = m_basenick + Util.RandomClass.Next(1, 99); 742 m_nick = m_basenick + Util.RandomClass.Next(1, 99);
719 m_log.Error("[IRC]: IRC SERVER reports NicknameInUse, trying " + m_nick); 743 m_log.Error("[IRC]: IRC SERVER reports NicknameInUse, trying " + m_nick);
@@ -723,9 +747,9 @@ namespace OpenSim.Region.Environment.Modules.Avatar.Chat
723 m_writer.WriteLine("JOIN " + m_channel); 747 m_writer.WriteLine("JOIN " + m_channel);
724 m_writer.Flush(); 748 m_writer.Flush();
725 break; 749 break;
726 case (int)ErrorReplies.NotRegistered: 750 case (int) ErrorReplies.NotRegistered:
727 break; 751 break;
728 case (int)Replies.EndOfMotd: 752 case (int) Replies.EndOfMotd:
729 break; 753 break;
730 } 754 }
731 } 755 }
@@ -733,19 +757,32 @@ namespace OpenSim.Region.Environment.Modules.Avatar.Chat
733 { 757 {
734 } 758 }
735 } 759 }
736 else 760 else
737 { 761 {
738 // Normal message 762 // Normal message
739 string commAct = commArgs[1]; 763 string commAct = commArgs[1];
740 switch (commAct) 764 switch (commAct)
741 { 765 {
742 case "JOIN": eventIrcJoin(commArgs); break; 766 case "JOIN":
743 case "PART": eventIrcPart(commArgs); break; 767 eventIrcJoin(commArgs);
744 case "MODE": eventIrcMode(commArgs); break; 768 break;
745 case "NICK": eventIrcNickChange(commArgs); break; 769 case "PART":
746 case "KICK": eventIrcKick(commArgs); break; 770 eventIrcPart(commArgs);
747 case "QUIT": eventIrcQuit(commArgs); break; 771 break;
748 case "PONG": break; // that's nice 772 case "MODE":
773 eventIrcMode(commArgs);
774 break;
775 case "NICK":
776 eventIrcNickChange(commArgs);
777 break;
778 case "KICK":
779 eventIrcKick(commArgs);
780 break;
781 case "QUIT":
782 eventIrcQuit(commArgs);
783 break;
784 case "PONG":
785 break; // that's nice
749 } 786 }
750 } 787 }
751 } 788 }
@@ -797,7 +834,7 @@ namespace OpenSim.Region.Environment.Modules.Avatar.Chat
797 { 834 {
798 KickMessage += commArgs[i] + " "; 835 KickMessage += commArgs[i] + " ";
799 } 836 }
800 BroadcastSim(UserKicker + " kicked " + UserKicked +" on "+IrcChannel+" saying "+KickMessage, m_nick); 837 BroadcastSim(UserKicker + " kicked " + UserKicked + " on " + IrcChannel + " saying " + KickMessage, m_nick);
801 if (UserKicked == m_nick) 838 if (UserKicked == m_nick)
802 { 839 {
803 BroadcastSim("Hey, that was me!!!", m_nick); 840 BroadcastSim("Hey, that was me!!!", m_nick);