aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs')
-rw-r--r--OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs397
1 files changed, 303 insertions, 94 deletions
diff --git a/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs b/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs
index 8358bc0..2c2c99c 100644
--- a/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs
@@ -28,8 +28,13 @@
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Text.RegularExpressions;
32
31using Nini.Config; 33using Nini.Config;
34using Mono.Addins;
35
32using OpenMetaverse; 36using OpenMetaverse;
37
33using OpenSim.Framework; 38using OpenSim.Framework;
34using OpenSim.Region.Framework.Interfaces; 39using OpenSim.Region.Framework.Interfaces;
35using OpenSim.Region.Framework.Scenes; 40using OpenSim.Region.Framework.Scenes;
@@ -85,7 +90,8 @@ using OpenSim.Region.Framework.Scenes;
85 90
86namespace OpenSim.Region.CoreModules.Scripting.WorldComm 91namespace OpenSim.Region.CoreModules.Scripting.WorldComm
87{ 92{
88 public class WorldCommModule : IRegionModule, IWorldComm 93 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "WorldCommModule")]
94 public class WorldCommModule : IWorldComm, INonSharedRegionModule
89 { 95 {
90 // private static readonly ILog m_log = 96 // private static readonly ILog m_log =
91 // LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 97 // LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@@ -98,9 +104,9 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
98 private int m_saydistance = 20; 104 private int m_saydistance = 20;
99 private int m_shoutdistance = 100; 105 private int m_shoutdistance = 100;
100 106
101 #region IRegionModule Members 107 #region INonSharedRegionModule Members
102 108
103 public void Initialise(Scene scene, IConfigSource config) 109 public void Initialise(IConfigSource config)
104 { 110 {
105 // wrap this in a try block so that defaults will work if 111 // wrap this in a try block so that defaults will work if
106 // the config file doesn't specify otherwise. 112 // the config file doesn't specify otherwise.
@@ -108,29 +114,49 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
108 int maxhandles = 64; 114 int maxhandles = 64;
109 try 115 try
110 { 116 {
111 m_whisperdistance = config.Configs["Chat"].GetInt("whisper_distance", m_whisperdistance); 117 m_whisperdistance = config.Configs["Chat"].GetInt(
112 m_saydistance = config.Configs["Chat"].GetInt("say_distance", m_saydistance); 118 "whisper_distance", m_whisperdistance);
113 m_shoutdistance = config.Configs["Chat"].GetInt("shout_distance", m_shoutdistance); 119 m_saydistance = config.Configs["Chat"].GetInt(
114 maxlisteners = config.Configs["LL-Functions"].GetInt("max_listens_per_region", maxlisteners); 120 "say_distance", m_saydistance);
115 maxhandles = config.Configs["LL-Functions"].GetInt("max_listens_per_script", maxhandles); 121 m_shoutdistance = config.Configs["Chat"].GetInt(
122 "shout_distance", m_shoutdistance);
123 maxlisteners = config.Configs["LL-Functions"].GetInt(
124 "max_listens_per_region", maxlisteners);
125 maxhandles = config.Configs["LL-Functions"].GetInt(
126 "max_listens_per_script", maxhandles);
116 } 127 }
117 catch (Exception) 128 catch (Exception)
118 { 129 {
119 } 130 }
120 if (maxlisteners < 1) maxlisteners = int.MaxValue; 131 if (maxlisteners < 1) maxlisteners = int.MaxValue;
121 if (maxhandles < 1) maxhandles = int.MaxValue; 132 if (maxhandles < 1) maxhandles = int.MaxValue;
133 m_listenerManager = new ListenerManager(maxlisteners, maxhandles);
134 m_pendingQ = new Queue();
135 m_pending = Queue.Synchronized(m_pendingQ);
136 }
122 137
138 public void PostInitialise()
139 {
140 }
141
142 public void AddRegion(Scene scene)
143 {
123 m_scene = scene; 144 m_scene = scene;
124 m_scene.RegisterModuleInterface<IWorldComm>(this); 145 m_scene.RegisterModuleInterface<IWorldComm>(this);
125 m_listenerManager = new ListenerManager(maxlisteners, maxhandles);
126 m_scene.EventManager.OnChatFromClient += DeliverClientMessage; 146 m_scene.EventManager.OnChatFromClient += DeliverClientMessage;
127 m_scene.EventManager.OnChatBroadcast += DeliverClientMessage; 147 m_scene.EventManager.OnChatBroadcast += DeliverClientMessage;
128 m_pendingQ = new Queue();
129 m_pending = Queue.Synchronized(m_pendingQ);
130 } 148 }
131 149
132 public void PostInitialise() 150 public void RegionLoaded(Scene scene) { }
151
152 public void RemoveRegion(Scene scene)
133 { 153 {
154 if (scene != m_scene)
155 return;
156
157 m_scene.UnregisterModuleInterface<IWorldComm>(this);
158 m_scene.EventManager.OnChatBroadcast -= DeliverClientMessage;
159 m_scene.EventManager.OnChatBroadcast -= DeliverClientMessage;
134 } 160 }
135 161
136 public void Close() 162 public void Close()
@@ -142,10 +168,7 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
142 get { return "WorldCommModule"; } 168 get { return "WorldCommModule"; }
143 } 169 }
144 170
145 public bool IsSharedModule 171 public Type ReplaceableInterface { get { return null; } }
146 {
147 get { return false; }
148 }
149 172
150 #endregion 173 #endregion
151 174
@@ -170,12 +193,42 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
170 /// <param name="hostID">UUID of the SceneObjectPart</param> 193 /// <param name="hostID">UUID of the SceneObjectPart</param>
171 /// <param name="channel">channel to listen on</param> 194 /// <param name="channel">channel to listen on</param>
172 /// <param name="name">name to filter on</param> 195 /// <param name="name">name to filter on</param>
173 /// <param name="id">key to filter on (user given, could be totally faked)</param> 196 /// <param name="id">
197 /// key to filter on (user given, could be totally faked)
198 /// </param>
174 /// <param name="msg">msg to filter on</param> 199 /// <param name="msg">msg to filter on</param>
175 /// <returns>number of the scripts handle</returns> 200 /// <returns>number of the scripts handle</returns>
176 public int Listen(uint localID, UUID itemID, UUID hostID, int channel, string name, UUID id, string msg) 201 public int Listen(uint localID, UUID itemID, UUID hostID, int channel,
202 string name, UUID id, string msg)
177 { 203 {
178 return m_listenerManager.AddListener(localID, itemID, hostID, channel, name, id, msg); 204 return m_listenerManager.AddListener(localID, itemID, hostID,
205 channel, name, id, msg);
206 }
207
208 /// <summary>
209 /// Create a listen event callback with the specified filters.
210 /// The parameters localID,itemID are needed to uniquely identify
211 /// the script during 'peek' time. Parameter hostID is needed to
212 /// determine the position of the script.
213 /// </summary>
214 /// <param name="localID">localID of the script engine</param>
215 /// <param name="itemID">UUID of the script engine</param>
216 /// <param name="hostID">UUID of the SceneObjectPart</param>
217 /// <param name="channel">channel to listen on</param>
218 /// <param name="name">name to filter on</param>
219 /// <param name="id">
220 /// key to filter on (user given, could be totally faked)
221 /// </param>
222 /// <param name="msg">msg to filter on</param>
223 /// <param name="regexBitfield">
224 /// Bitfield indicating which strings should be processed as regex.
225 /// </param>
226 /// <returns>number of the scripts handle</returns>
227 public int Listen(uint localID, UUID itemID, UUID hostID, int channel,
228 string name, UUID id, string msg, int regexBitfield)
229 {
230 return m_listenerManager.AddListener(localID, itemID, hostID,
231 channel, name, id, msg, regexBitfield);
179 } 232 }
180 233
181 /// <summary> 234 /// <summary>
@@ -224,7 +277,7 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
224 277
225 if ((source = m_scene.GetSceneObjectPart(id)) != null) 278 if ((source = m_scene.GetSceneObjectPart(id)) != null)
226 position = source.AbsolutePosition; 279 position = source.AbsolutePosition;
227 else if ((avatar = m_scene.GetScenePresence(id)) != null) 280 else if ((avatar = m_scene.GetScenePresence(id)) != null)
228 position = avatar.AbsolutePosition; 281 position = avatar.AbsolutePosition;
229 else if (ChatTypeEnum.Region == type) 282 else if (ChatTypeEnum.Region == type)
230 position = CenterOfRegion; 283 position = CenterOfRegion;
@@ -247,7 +300,8 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
247 /// <param name="name">name of sender (object or avatar)</param> 300 /// <param name="name">name of sender (object or avatar)</param>
248 /// <param name="id">key of sender (object or avatar)</param> 301 /// <param name="id">key of sender (object or avatar)</param>
249 /// <param name="msg">msg to sent</param> 302 /// <param name="msg">msg to sent</param>
250 public void DeliverMessage(ChatTypeEnum type, int channel, string name, UUID id, string msg, Vector3 position) 303 public void DeliverMessage(ChatTypeEnum type, int channel,
304 string name, UUID id, string msg, Vector3 position)
251 { 305 {
252 // m_log.DebugFormat("[WorldComm] got[2] type {0}, channel {1}, name {2}, id {3}, msg {4}", 306 // m_log.DebugFormat("[WorldComm] got[2] type {0}, channel {1}, name {2}, id {3}, msg {4}",
253 // type, channel, name, id, msg); 307 // type, channel, name, id, msg);
@@ -255,17 +309,21 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
255 // Determine which listen event filters match the given set of arguments, this results 309 // Determine which listen event filters match the given set of arguments, this results
256 // in a limited set of listeners, each belonging a host. If the host is in range, add them 310 // in a limited set of listeners, each belonging a host. If the host is in range, add them
257 // to the pending queue. 311 // to the pending queue.
258 foreach (ListenerInfo li in m_listenerManager.GetListeners(UUID.Zero, channel, name, id, msg)) 312 foreach (ListenerInfo li
313 in m_listenerManager.GetListeners(UUID.Zero, channel,
314 name, id, msg))
259 { 315 {
260 // Dont process if this message is from yourself! 316 // Dont process if this message is from yourself!
261 if (li.GetHostID().Equals(id)) 317 if (li.GetHostID().Equals(id))
262 continue; 318 continue;
263 319
264 SceneObjectPart sPart = m_scene.GetSceneObjectPart(li.GetHostID()); 320 SceneObjectPart sPart = m_scene.GetSceneObjectPart(
321 li.GetHostID());
265 if (sPart == null) 322 if (sPart == null)
266 continue; 323 continue;
267 324
268 double dis = Util.GetDistanceTo(sPart.AbsolutePosition, position); 325 double dis = Util.GetDistanceTo(sPart.AbsolutePosition,
326 position);
269 switch (type) 327 switch (type)
270 { 328 {
271 case ChatTypeEnum.Whisper: 329 case ChatTypeEnum.Whisper:
@@ -308,14 +366,16 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
308 /// <param name='msg'> 366 /// <param name='msg'>
309 /// Message. 367 /// Message.
310 /// </param> 368 /// </param>
311 public void DeliverMessageTo(UUID target, int channel, Vector3 pos, string name, UUID id, string msg) 369 public void DeliverMessageTo(UUID target, int channel, Vector3 pos,
370 string name, UUID id, string msg)
312 { 371 {
313 // Is id an avatar? 372 // Is id an avatar?
314 ScenePresence sp = m_scene.GetScenePresence(target); 373 ScenePresence sp = m_scene.GetScenePresence(target);
315 374
316 if (sp != null) 375 if (sp != null)
317 { 376 {
318 // ignore if a child agent this is restricted to inside one region 377 // ignore if a child agent this is restricted to inside one
378 // region
319 if (sp.IsChildAgent) 379 if (sp.IsChildAgent)
320 return; 380 return;
321 381
@@ -324,8 +384,9 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
324 // non zero channel messages only go to the attachments 384 // non zero channel messages only go to the attachments
325 if (channel == 0) 385 if (channel == 0)
326 { 386 {
327 m_scene.SimChatToAgent(target, Utils.StringToBytes(msg), pos, name, id, false); 387 m_scene.SimChatToAgent(target, Utils.StringToBytes(msg),
328 } 388 pos, name, id, false);
389 }
329 else 390 else
330 { 391 {
331 List<SceneObjectGroup> attachments = sp.GetAttachments(); 392 List<SceneObjectGroup> attachments = sp.GetAttachments();
@@ -341,13 +402,18 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
341 } 402 }
342 403
343 // Need to check each attachment 404 // Need to check each attachment
344 foreach (ListenerInfo li in m_listenerManager.GetListeners(UUID.Zero, channel, name, id, msg)) 405 foreach (ListenerInfo li
406 in m_listenerManager.GetListeners(UUID.Zero,
407 channel, name, id, msg))
345 { 408 {
346 if (li.GetHostID().Equals(id)) 409 if (li.GetHostID().Equals(id))
347 continue; 410 continue;
348 411
349 if (m_scene.GetSceneObjectPart(li.GetHostID()) == null) 412 if (m_scene.GetSceneObjectPart(
413 li.GetHostID()) == null)
414 {
350 continue; 415 continue;
416 }
351 417
352 if (targets.Contains(li.GetHostID())) 418 if (targets.Contains(li.GetHostID()))
353 QueueMessage(new ListenerInfo(li, name, id, msg)); 419 QueueMessage(new ListenerInfo(li, name, id, msg));
@@ -358,17 +424,20 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
358 } 424 }
359 425
360 // No avatar found so look for an object 426 // No avatar found so look for an object
361 foreach (ListenerInfo li in m_listenerManager.GetListeners(UUID.Zero, channel, name, id, msg)) 427 foreach (ListenerInfo li
428 in m_listenerManager.GetListeners(UUID.Zero, channel,
429 name, id, msg))
362 { 430 {
363 // Dont process if this message is from yourself! 431 // Dont process if this message is from yourself!
364 if (li.GetHostID().Equals(id)) 432 if (li.GetHostID().Equals(id))
365 continue; 433 continue;
366 434
367 SceneObjectPart sPart = m_scene.GetSceneObjectPart(li.GetHostID()); 435 SceneObjectPart sPart = m_scene.GetSceneObjectPart(
436 li.GetHostID());
368 if (sPart == null) 437 if (sPart == null)
369 continue; 438 continue;
370 439
371 if ( li.GetHostID().Equals(target)) 440 if (li.GetHostID().Equals(target))
372 { 441 {
373 QueueMessage(new ListenerInfo(li, name, id, msg)); 442 QueueMessage(new ListenerInfo(li, name, id, msg));
374 break; 443 break;
@@ -422,9 +491,15 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
422 private void DeliverClientMessage(Object sender, OSChatMessage e) 491 private void DeliverClientMessage(Object sender, OSChatMessage e)
423 { 492 {
424 if (null != e.Sender) 493 if (null != e.Sender)
425 DeliverMessage(e.Type, e.Channel, e.Sender.Name, e.Sender.AgentId, e.Message, e.Position); 494 {
495 DeliverMessage(e.Type, e.Channel, e.Sender.Name,
496 e.Sender.AgentId, e.Message, e.Position);
497 }
426 else 498 else
427 DeliverMessage(e.Type, e.Channel, e.From, UUID.Zero, e.Message, e.Position); 499 {
500 DeliverMessage(e.Type, e.Channel, e.From, UUID.Zero,
501 e.Message, e.Position);
502 }
428 } 503 }
429 504
430 public Object[] GetSerializationData(UUID itemID) 505 public Object[] GetSerializationData(UUID itemID)
@@ -441,7 +516,8 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
441 516
442 public class ListenerManager 517 public class ListenerManager
443 { 518 {
444 private Dictionary<int, List<ListenerInfo>> m_listeners = new Dictionary<int, List<ListenerInfo>>(); 519 private Dictionary<int, List<ListenerInfo>> m_listeners =
520 new Dictionary<int, List<ListenerInfo>>();
445 private int m_maxlisteners; 521 private int m_maxlisteners;
446 private int m_maxhandles; 522 private int m_maxhandles;
447 private int m_curlisteners; 523 private int m_curlisteners;
@@ -465,15 +541,25 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
465 m_curlisteners = 0; 541 m_curlisteners = 0;
466 } 542 }
467 543
468 public int AddListener(uint localID, UUID itemID, UUID hostID, int channel, string name, UUID id, string msg) 544 public int AddListener(uint localID, UUID itemID, UUID hostID,
545 int channel, string name, UUID id, string msg)
546 {
547 return AddListener(localID, itemID, hostID, channel, name, id,
548 msg, 0);
549 }
550
551 public int AddListener(uint localID, UUID itemID, UUID hostID,
552 int channel, string name, UUID id, string msg,
553 int regexBitfield)
469 { 554 {
470 // do we already have a match on this particular filter event? 555 // do we already have a match on this particular filter event?
471 List<ListenerInfo> coll = GetListeners(itemID, channel, name, id, msg); 556 List<ListenerInfo> coll = GetListeners(itemID, channel, name, id,
557 msg);
472 558
473 if (coll.Count > 0) 559 if (coll.Count > 0)
474 { 560 {
475 // special case, called with same filter settings, return same handle 561 // special case, called with same filter settings, return same
476 // (2008-05-02, tested on 1.21.1 server, still holds) 562 // handle (2008-05-02, tested on 1.21.1 server, still holds)
477 return coll[0].GetHandle(); 563 return coll[0].GetHandle();
478 } 564 }
479 565
@@ -485,16 +571,19 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
485 571
486 if (newHandle > 0) 572 if (newHandle > 0)
487 { 573 {
488 ListenerInfo li = new ListenerInfo(newHandle, localID, itemID, hostID, channel, name, id, msg); 574 ListenerInfo li = new ListenerInfo(newHandle, localID,
575 itemID, hostID, channel, name, id, msg,
576 regexBitfield);
489 577
490 List<ListenerInfo> listeners; 578 List<ListenerInfo> listeners;
491 if (!m_listeners.TryGetValue(channel,out listeners)) 579 if (!m_listeners.TryGetValue(
492 { 580 channel, out listeners))
493 listeners = new List<ListenerInfo>(); 581 {
494 m_listeners.Add(channel, listeners); 582 listeners = new List<ListenerInfo>();
495 } 583 m_listeners.Add(channel, listeners);
496 listeners.Add(li); 584 }
497 m_curlisteners++; 585 listeners.Add(li);
586 m_curlisteners++;
498 587
499 return newHandle; 588 return newHandle;
500 } 589 }
@@ -507,11 +596,13 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
507 { 596 {
508 lock (m_listeners) 597 lock (m_listeners)
509 { 598 {
510 foreach (KeyValuePair<int,List<ListenerInfo>> lis in m_listeners) 599 foreach (KeyValuePair<int, List<ListenerInfo>> lis
600 in m_listeners)
511 { 601 {
512 foreach (ListenerInfo li in lis.Value) 602 foreach (ListenerInfo li in lis.Value)
513 { 603 {
514 if (li.GetItemID().Equals(itemID) && li.GetHandle().Equals(handle)) 604 if (li.GetItemID().Equals(itemID) &&
605 li.GetHandle().Equals(handle))
515 { 606 {
516 lis.Value.Remove(li); 607 lis.Value.Remove(li);
517 if (lis.Value.Count == 0) 608 if (lis.Value.Count == 0)
@@ -534,13 +625,15 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
534 625
535 lock (m_listeners) 626 lock (m_listeners)
536 { 627 {
537 foreach (KeyValuePair<int,List<ListenerInfo>> lis in m_listeners) 628 foreach (KeyValuePair<int, List<ListenerInfo>> lis
629 in m_listeners)
538 { 630 {
539 foreach (ListenerInfo li in lis.Value) 631 foreach (ListenerInfo li in lis.Value)
540 { 632 {
541 if (li.GetItemID().Equals(itemID)) 633 if (li.GetItemID().Equals(itemID))
542 { 634 {
543 // store them first, else the enumerated bails on us 635 // store them first, else the enumerated bails on
636 // us
544 removedListeners.Add(li); 637 removedListeners.Add(li);
545 } 638 }
546 } 639 }
@@ -567,11 +660,13 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
567 { 660 {
568 lock (m_listeners) 661 lock (m_listeners)
569 { 662 {
570 foreach (KeyValuePair<int,List<ListenerInfo>> lis in m_listeners) 663 foreach (KeyValuePair<int, List<ListenerInfo>> lis
664 in m_listeners)
571 { 665 {
572 foreach (ListenerInfo li in lis.Value) 666 foreach (ListenerInfo li in lis.Value)
573 { 667 {
574 if (li.GetItemID().Equals(itemID) && li.GetHandle() == handle) 668 if (li.GetItemID().Equals(itemID) &&
669 li.GetHandle() == handle)
575 { 670 {
576 li.Activate(); 671 li.Activate();
577 // only one, bail out 672 // only one, bail out
@@ -586,11 +681,13 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
586 { 681 {
587 lock (m_listeners) 682 lock (m_listeners)
588 { 683 {
589 foreach (KeyValuePair<int,List<ListenerInfo>> lis in m_listeners) 684 foreach (KeyValuePair<int, List<ListenerInfo>> lis
685 in m_listeners)
590 { 686 {
591 foreach (ListenerInfo li in lis.Value) 687 foreach (ListenerInfo li in lis.Value)
592 { 688 {
593 if (li.GetItemID().Equals(itemID) && li.GetHandle() == handle) 689 if (li.GetItemID().Equals(itemID) &&
690 li.GetHandle() == handle)
594 { 691 {
595 li.Deactivate(); 692 li.Deactivate();
596 // only one, bail out 693 // only one, bail out
@@ -601,19 +698,24 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
601 } 698 }
602 } 699 }
603 700
604 // non-locked access, since its always called in the context of the lock 701 /// <summary>
702 /// non-locked access, since its always called in the context of the
703 /// lock
704 /// </summary>
705 /// <param name="itemID"></param>
706 /// <returns></returns>
605 private int GetNewHandle(UUID itemID) 707 private int GetNewHandle(UUID itemID)
606 { 708 {
607 List<int> handles = new List<int>(); 709 List<int> handles = new List<int>();
608 710
609 // build a list of used keys for this specific itemID... 711 // build a list of used keys for this specific itemID...
610 foreach (KeyValuePair<int,List<ListenerInfo>> lis in m_listeners) 712 foreach (KeyValuePair<int, List<ListenerInfo>> lis in m_listeners)
611 { 713 {
612 foreach (ListenerInfo li in lis.Value) 714 foreach (ListenerInfo li in lis.Value)
613 { 715 {
614 if (li.GetItemID().Equals(itemID)) 716 if (li.GetItemID().Equals(itemID))
615 handles.Add(li.GetHandle()); 717 handles.Add(li.GetHandle());
616 } 718 }
617 } 719 }
618 720
619 // Note: 0 is NOT a valid handle for llListen() to return 721 // Note: 0 is NOT a valid handle for llListen() to return
@@ -626,17 +728,46 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
626 return -1; 728 return -1;
627 } 729 }
628 730
629 // Theres probably a more clever and efficient way to 731 /// These are duplicated from ScriptBaseClass
630 // do this, maybe with regex. 732 /// http://opensimulator.org/mantis/view.php?id=6106#c21945
631 // PM2008: Ha, one could even be smart and define a specialized Enumerator. 733 #region Constants for the bitfield parameter of osListenRegex
632 public List<ListenerInfo> GetListeners(UUID itemID, int channel, string name, UUID id, string msg) 734
735 /// <summary>
736 /// process name parameter as regex
737 /// </summary>
738 public const int OS_LISTEN_REGEX_NAME = 0x1;
739
740 /// <summary>
741 /// process message parameter as regex
742 /// </summary>
743 public const int OS_LISTEN_REGEX_MESSAGE = 0x2;
744
745 #endregion
746
747 /// <summary>
748 /// Get listeners matching the input parameters.
749 /// </summary>
750 /// <remarks>
751 /// Theres probably a more clever and efficient way to do this, maybe
752 /// with regex.
753 /// PM2008: Ha, one could even be smart and define a specialized
754 /// Enumerator.
755 /// </remarks>
756 /// <param name="itemID"></param>
757 /// <param name="channel"></param>
758 /// <param name="name"></param>
759 /// <param name="id"></param>
760 /// <param name="msg"></param>
761 /// <returns></returns>
762 public List<ListenerInfo> GetListeners(UUID itemID, int channel,
763 string name, UUID id, string msg)
633 { 764 {
634 List<ListenerInfo> collection = new List<ListenerInfo>(); 765 List<ListenerInfo> collection = new List<ListenerInfo>();
635 766
636 lock (m_listeners) 767 lock (m_listeners)
637 { 768 {
638 List<ListenerInfo> listeners; 769 List<ListenerInfo> listeners;
639 if (!m_listeners.TryGetValue(channel,out listeners)) 770 if (!m_listeners.TryGetValue(channel, out listeners))
640 { 771 {
641 return collection; 772 return collection;
642 } 773 }
@@ -647,11 +778,15 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
647 { 778 {
648 continue; 779 continue;
649 } 780 }
650 if (!itemID.Equals(UUID.Zero) && !li.GetItemID().Equals(itemID)) 781 if (!itemID.Equals(UUID.Zero) &&
782 !li.GetItemID().Equals(itemID))
651 { 783 {
652 continue; 784 continue;
653 } 785 }
654 if (li.GetName().Length > 0 && !li.GetName().Equals(name)) 786 if (li.GetName().Length > 0 && (
787 ((li.RegexBitfield & OS_LISTEN_REGEX_NAME) != OS_LISTEN_REGEX_NAME && !li.GetName().Equals(name)) ||
788 ((li.RegexBitfield & OS_LISTEN_REGEX_NAME) == OS_LISTEN_REGEX_NAME && !Regex.IsMatch(name, li.GetName()))
789 ))
655 { 790 {
656 continue; 791 continue;
657 } 792 }
@@ -659,7 +794,10 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
659 { 794 {
660 continue; 795 continue;
661 } 796 }
662 if (li.GetMessage().Length > 0 && !li.GetMessage().Equals(msg)) 797 if (li.GetMessage().Length > 0 && (
798 ((li.RegexBitfield & OS_LISTEN_REGEX_MESSAGE) != OS_LISTEN_REGEX_MESSAGE && !li.GetMessage().Equals(msg)) ||
799 ((li.RegexBitfield & OS_LISTEN_REGEX_MESSAGE) == OS_LISTEN_REGEX_MESSAGE && !Regex.IsMatch(msg, li.GetMessage()))
800 ))
663 { 801 {
664 continue; 802 continue;
665 } 803 }
@@ -692,10 +830,13 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
692 { 830 {
693 int idx = 0; 831 int idx = 0;
694 Object[] item = new Object[6]; 832 Object[] item = new Object[6];
833 int dataItemLength = 6;
695 834
696 while (idx < data.Length) 835 while (idx < data.Length)
697 { 836 {
698 Array.Copy(data, idx, item, 0, 6); 837 dataItemLength = (idx + 7 == data.Length || (idx + 7 < data.Length && data[idx + 7] is bool)) ? 7 : 6;
838 item = new Object[dataItemLength];
839 Array.Copy(data, idx, item, 0, dataItemLength);
699 840
700 ListenerInfo info = 841 ListenerInfo info =
701 ListenerInfo.FromData(localID, itemID, hostID, item); 842 ListenerInfo.FromData(localID, itemID, hostID, item);
@@ -703,39 +844,98 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
703 lock (m_listeners) 844 lock (m_listeners)
704 { 845 {
705 if (!m_listeners.ContainsKey((int)item[2])) 846 if (!m_listeners.ContainsKey((int)item[2]))
706 m_listeners.Add((int)item[2], new List<ListenerInfo>()); 847 {
848 m_listeners.Add((int)item[2],
849 new List<ListenerInfo>());
850 }
707 m_listeners[(int)item[2]].Add(info); 851 m_listeners[(int)item[2]].Add(info);
708 } 852 }
709 853
710 idx+=6; 854 idx += dataItemLength;
711 } 855 }
712 } 856 }
713 } 857 }
714 858
715 public class ListenerInfo: IWorldCommListenerInfo 859 public class ListenerInfo : IWorldCommListenerInfo
716 { 860 {
717 private bool m_active; // Listener is active or not 861 /// <summary>
718 private int m_handle; // Assigned handle of this listener 862 /// Listener is active or not
719 private uint m_localID; // Local ID from script engine 863 /// </summary>
720 private UUID m_itemID; // ID of the host script engine 864 private bool m_active;
721 private UUID m_hostID; // ID of the host/scene part
722 private int m_channel; // Channel
723 private UUID m_id; // ID to filter messages from
724 private string m_name; // Object name to filter messages from
725 private string m_message; // The message
726 865
727 public ListenerInfo(int handle, uint localID, UUID ItemID, UUID hostID, int channel, string name, UUID id, string message) 866 /// <summary>
867 /// Assigned handle of this listener
868 /// </summary>
869 private int m_handle;
870
871 /// <summary>
872 /// Local ID from script engine
873 /// </summary>
874 private uint m_localID;
875
876 /// <summary>
877 /// ID of the host script engine
878 /// </summary>
879 private UUID m_itemID;
880
881 /// <summary>
882 /// ID of the host/scene part
883 /// </summary>
884 private UUID m_hostID;
885
886 /// <summary>
887 /// Channel
888 /// </summary>
889 private int m_channel;
890
891 /// <summary>
892 /// ID to filter messages from
893 /// </summary>
894 private UUID m_id;
895
896 /// <summary>
897 /// Object name to filter messages from
898 /// </summary>
899 private string m_name;
900
901 /// <summary>
902 /// The message
903 /// </summary>
904 private string m_message;
905
906 public ListenerInfo(int handle, uint localID, UUID ItemID,
907 UUID hostID, int channel, string name, UUID id,
908 string message)
909 {
910 Initialise(handle, localID, ItemID, hostID, channel, name, id,
911 message, 0);
912 }
913
914 public ListenerInfo(int handle, uint localID, UUID ItemID,
915 UUID hostID, int channel, string name, UUID id,
916 string message, int regexBitfield)
728 { 917 {
729 Initialise(handle, localID, ItemID, hostID, channel, name, id, message); 918 Initialise(handle, localID, ItemID, hostID, channel, name, id,
919 message, regexBitfield);
730 } 920 }
731 921
732 public ListenerInfo(ListenerInfo li, string name, UUID id, string message) 922 public ListenerInfo(ListenerInfo li, string name, UUID id,
923 string message)
733 { 924 {
734 Initialise(li.m_handle, li.m_localID, li.m_itemID, li.m_hostID, li.m_channel, name, id, message); 925 Initialise(li.m_handle, li.m_localID, li.m_itemID, li.m_hostID,
926 li.m_channel, name, id, message, 0);
735 } 927 }
736 928
737 private void Initialise(int handle, uint localID, UUID ItemID, UUID hostID, int channel, string name, 929 public ListenerInfo(ListenerInfo li, string name, UUID id,
738 UUID id, string message) 930 string message, int regexBitfield)
931 {
932 Initialise(li.m_handle, li.m_localID, li.m_itemID, li.m_hostID,
933 li.m_channel, name, id, message, regexBitfield);
934 }
935
936 private void Initialise(int handle, uint localID, UUID ItemID,
937 UUID hostID, int channel, string name, UUID id,
938 string message, int regexBitfield)
739 { 939 {
740 m_active = true; 940 m_active = true;
741 m_handle = handle; 941 m_handle = handle;
@@ -746,11 +946,12 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
746 m_name = name; 946 m_name = name;
747 m_id = id; 947 m_id = id;
748 m_message = message; 948 m_message = message;
949 RegexBitfield = regexBitfield;
749 } 950 }
750 951
751 public Object[] GetSerializationData() 952 public Object[] GetSerializationData()
752 { 953 {
753 Object[] data = new Object[6]; 954 Object[] data = new Object[7];
754 955
755 data[0] = m_active; 956 data[0] = m_active;
756 data[1] = m_handle; 957 data[1] = m_handle;
@@ -758,16 +959,22 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
758 data[3] = m_name; 959 data[3] = m_name;
759 data[4] = m_id; 960 data[4] = m_id;
760 data[5] = m_message; 961 data[5] = m_message;
962 data[6] = RegexBitfield;
761 963
762 return data; 964 return data;
763 } 965 }
764 966
765 public static ListenerInfo FromData(uint localID, UUID ItemID, UUID hostID, Object[] data) 967 public static ListenerInfo FromData(uint localID, UUID ItemID,
968 UUID hostID, Object[] data)
766 { 969 {
767 ListenerInfo linfo = new ListenerInfo((int)data[1], localID, 970 ListenerInfo linfo = new ListenerInfo((int)data[1], localID,
768 ItemID, hostID, (int)data[2], (string)data[3], 971 ItemID, hostID, (int)data[2], (string)data[3],
769 (UUID)data[4], (string)data[5]); 972 (UUID)data[4], (string)data[5]);
770 linfo.m_active=(bool)data[0]; 973 linfo.m_active = (bool)data[0];
974 if (data.Length >= 7)
975 {
976 linfo.RegexBitfield = (int)data[6];
977 }
771 978
772 return linfo; 979 return linfo;
773 } 980 }
@@ -826,5 +1033,7 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
826 { 1033 {
827 return m_id; 1034 return m_id;
828 } 1035 }
1036
1037 public int RegexBitfield { get; private set; }
829 } 1038 }
830} 1039}