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.cs375
1 files changed, 287 insertions, 88 deletions
diff --git a/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs b/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs
index 07bb291..87a0537 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);
@@ -100,9 +106,9 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
100 private int m_saydistance = 20; 106 private int m_saydistance = 20;
101 private int m_shoutdistance = 100; 107 private int m_shoutdistance = 100;
102 108
103 #region IRegionModule Members 109 #region INonSharedRegionModule Members
104 110
105 public void Initialise(Scene scene, IConfigSource config) 111 public void Initialise(IConfigSource config)
106 { 112 {
107 // wrap this in a try block so that defaults will work if 113 // wrap this in a try block so that defaults will work if
108 // the config file doesn't specify otherwise. 114 // the config file doesn't specify otherwise.
@@ -110,29 +116,49 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
110 int maxhandles = 64; 116 int maxhandles = 64;
111 try 117 try
112 { 118 {
113 m_whisperdistance = config.Configs["Chat"].GetInt("whisper_distance", m_whisperdistance); 119 m_whisperdistance = config.Configs["Chat"].GetInt(
114 m_saydistance = config.Configs["Chat"].GetInt("say_distance", m_saydistance); 120 "whisper_distance", m_whisperdistance);
115 m_shoutdistance = config.Configs["Chat"].GetInt("shout_distance", m_shoutdistance); 121 m_saydistance = config.Configs["Chat"].GetInt(
116 maxlisteners = config.Configs["LL-Functions"].GetInt("max_listens_per_region", maxlisteners); 122 "say_distance", m_saydistance);
117 maxhandles = config.Configs["LL-Functions"].GetInt("max_listens_per_script", maxhandles); 123 m_shoutdistance = config.Configs["Chat"].GetInt(
124 "shout_distance", m_shoutdistance);
125 maxlisteners = config.Configs["LL-Functions"].GetInt(
126 "max_listens_per_region", maxlisteners);
127 maxhandles = config.Configs["LL-Functions"].GetInt(
128 "max_listens_per_script", maxhandles);
118 } 129 }
119 catch (Exception) 130 catch (Exception)
120 { 131 {
121 } 132 }
122 if (maxlisteners < 1) maxlisteners = int.MaxValue; 133 if (maxlisteners < 1) maxlisteners = int.MaxValue;
123 if (maxhandles < 1) maxhandles = int.MaxValue; 134 if (maxhandles < 1) maxhandles = int.MaxValue;
135 m_listenerManager = new ListenerManager(maxlisteners, maxhandles);
136 m_pendingQ = new Queue();
137 m_pending = Queue.Synchronized(m_pendingQ);
138 }
124 139
140 public void PostInitialise()
141 {
142 }
143
144 public void AddRegion(Scene scene)
145 {
125 m_scene = scene; 146 m_scene = scene;
126 m_scene.RegisterModuleInterface<IWorldComm>(this); 147 m_scene.RegisterModuleInterface<IWorldComm>(this);
127 m_listenerManager = new ListenerManager(maxlisteners, maxhandles);
128 m_scene.EventManager.OnChatFromClient += DeliverClientMessage; 148 m_scene.EventManager.OnChatFromClient += DeliverClientMessage;
129 m_scene.EventManager.OnChatBroadcast += DeliverClientMessage; 149 m_scene.EventManager.OnChatBroadcast += DeliverClientMessage;
130 m_pendingQ = new Queue();
131 m_pending = Queue.Synchronized(m_pendingQ);
132 } 150 }
133 151
134 public void PostInitialise() 152 public void RegionLoaded(Scene scene) { }
153
154 public void RemoveRegion(Scene scene)
135 { 155 {
156 if (scene != m_scene)
157 return;
158
159 m_scene.UnregisterModuleInterface<IWorldComm>(this);
160 m_scene.EventManager.OnChatBroadcast -= DeliverClientMessage;
161 m_scene.EventManager.OnChatBroadcast -= DeliverClientMessage;
136 } 162 }
137 163
138 public void Close() 164 public void Close()
@@ -144,10 +170,7 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
144 get { return "WorldCommModule"; } 170 get { return "WorldCommModule"; }
145 } 171 }
146 172
147 public bool IsSharedModule 173 public Type ReplaceableInterface { get { return null; } }
148 {
149 get { return false; }
150 }
151 174
152 #endregion 175 #endregion
153 176
@@ -172,12 +195,42 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
172 /// <param name="hostID">UUID of the SceneObjectPart</param> 195 /// <param name="hostID">UUID of the SceneObjectPart</param>
173 /// <param name="channel">channel to listen on</param> 196 /// <param name="channel">channel to listen on</param>
174 /// <param name="name">name to filter on</param> 197 /// <param name="name">name to filter on</param>
175 /// <param name="id">key to filter on (user given, could be totally faked)</param> 198 /// <param name="id">
199 /// key to filter on (user given, could be totally faked)
200 /// </param>
201 /// <param name="msg">msg to filter on</param>
202 /// <returns>number of the scripts handle</returns>
203 public int Listen(uint localID, UUID itemID, UUID hostID, int channel,
204 string name, UUID id, string msg)
205 {
206 return m_listenerManager.AddListener(localID, itemID, hostID,
207 channel, name, id, msg);
208 }
209
210 /// <summary>
211 /// Create a listen event callback with the specified filters.
212 /// The parameters localID,itemID are needed to uniquely identify
213 /// the script during 'peek' time. Parameter hostID is needed to
214 /// determine the position of the script.
215 /// </summary>
216 /// <param name="localID">localID of the script engine</param>
217 /// <param name="itemID">UUID of the script engine</param>
218 /// <param name="hostID">UUID of the SceneObjectPart</param>
219 /// <param name="channel">channel to listen on</param>
220 /// <param name="name">name to filter on</param>
221 /// <param name="id">
222 /// key to filter on (user given, could be totally faked)
223 /// </param>
176 /// <param name="msg">msg to filter on</param> 224 /// <param name="msg">msg to filter on</param>
225 /// <param name="regexBitfield">
226 /// Bitfield indicating which strings should be processed as regex.
227 /// </param>
177 /// <returns>number of the scripts handle</returns> 228 /// <returns>number of the scripts handle</returns>
178 public int Listen(uint localID, UUID itemID, UUID hostID, int channel, string name, UUID id, string msg) 229 public int Listen(uint localID, UUID itemID, UUID hostID, int channel,
230 string name, UUID id, string msg, int regexBitfield)
179 { 231 {
180 return m_listenerManager.AddListener(localID, itemID, hostID, channel, name, id, msg); 232 return m_listenerManager.AddListener(localID, itemID, hostID,
233 channel, name, id, msg, regexBitfield);
181 } 234 }
182 235
183 /// <summary> 236 /// <summary>
@@ -226,7 +279,7 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
226 279
227 if ((source = m_scene.GetSceneObjectPart(id)) != null) 280 if ((source = m_scene.GetSceneObjectPart(id)) != null)
228 position = source.AbsolutePosition; 281 position = source.AbsolutePosition;
229 else if ((avatar = m_scene.GetScenePresence(id)) != null) 282 else if ((avatar = m_scene.GetScenePresence(id)) != null)
230 position = avatar.AbsolutePosition; 283 position = avatar.AbsolutePosition;
231 else if (ChatTypeEnum.Region == type) 284 else if (ChatTypeEnum.Region == type)
232 position = CenterOfRegion; 285 position = CenterOfRegion;
@@ -249,7 +302,8 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
249 /// <param name="name">name of sender (object or avatar)</param> 302 /// <param name="name">name of sender (object or avatar)</param>
250 /// <param name="id">key of sender (object or avatar)</param> 303 /// <param name="id">key of sender (object or avatar)</param>
251 /// <param name="msg">msg to sent</param> 304 /// <param name="msg">msg to sent</param>
252 public void DeliverMessage(ChatTypeEnum type, int channel, string name, UUID id, string msg, Vector3 position) 305 public void DeliverMessage(ChatTypeEnum type, int channel,
306 string name, UUID id, string msg, Vector3 position)
253 { 307 {
254 // m_log.DebugFormat("[WorldComm] got[2] type {0}, channel {1}, name {2}, id {3}, msg {4}", 308 // m_log.DebugFormat("[WorldComm] got[2] type {0}, channel {1}, name {2}, id {3}, msg {4}",
255 // type, channel, name, id, msg); 309 // type, channel, name, id, msg);
@@ -257,17 +311,21 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
257 // Determine which listen event filters match the given set of arguments, this results 311 // Determine which listen event filters match the given set of arguments, this results
258 // in a limited set of listeners, each belonging a host. If the host is in range, add them 312 // in a limited set of listeners, each belonging a host. If the host is in range, add them
259 // to the pending queue. 313 // to the pending queue.
260 foreach (ListenerInfo li in m_listenerManager.GetListeners(UUID.Zero, channel, name, id, msg)) 314 foreach (ListenerInfo li
315 in m_listenerManager.GetListeners(UUID.Zero, channel,
316 name, id, msg))
261 { 317 {
262 // Dont process if this message is from yourself! 318 // Dont process if this message is from yourself!
263 if (li.GetHostID().Equals(id)) 319 if (li.GetHostID().Equals(id))
264 continue; 320 continue;
265 321
266 SceneObjectPart sPart = m_scene.GetSceneObjectPart(li.GetHostID()); 322 SceneObjectPart sPart = m_scene.GetSceneObjectPart(
323 li.GetHostID());
267 if (sPart == null) 324 if (sPart == null)
268 continue; 325 continue;
269 326
270 double dis = Util.GetDistanceTo(sPart.AbsolutePosition, position); 327 double dis = Util.GetDistanceTo(sPart.AbsolutePosition,
328 position);
271 switch (type) 329 switch (type)
272 { 330 {
273 case ChatTypeEnum.Whisper: 331 case ChatTypeEnum.Whisper:
@@ -326,7 +384,7 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
326 if (channel == 0) 384 if (channel == 0)
327 { 385 {
328 // Channel 0 goes to viewer ONLY 386 // Channel 0 goes to viewer ONLY
329 m_scene.SimChat(Utils.StringToBytes(msg), ChatTypeEnum.Broadcast, 0, pos, name, id, false, false, target); 387 m_scene.SimChat(Utils.StringToBytes(msg), ChatTypeEnum.Broadcast, 0, pos, name, id, target, false, false);
330 return true; 388 return true;
331 } 389 }
332 390
@@ -369,11 +427,12 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
369 if (li.GetHostID().Equals(id)) 427 if (li.GetHostID().Equals(id))
370 continue; 428 continue;
371 429
372 SceneObjectPart sPart = m_scene.GetSceneObjectPart(li.GetHostID()); 430 SceneObjectPart sPart = m_scene.GetSceneObjectPart(
431 li.GetHostID());
373 if (sPart == null) 432 if (sPart == null)
374 continue; 433 continue;
375 434
376 if ( li.GetHostID().Equals(target)) 435 if (li.GetHostID().Equals(target))
377 { 436 {
378 QueueMessage(new ListenerInfo(li, name, id, msg)); 437 QueueMessage(new ListenerInfo(li, name, id, msg));
379 break; 438 break;
@@ -427,9 +486,15 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
427 private void DeliverClientMessage(Object sender, OSChatMessage e) 486 private void DeliverClientMessage(Object sender, OSChatMessage e)
428 { 487 {
429 if (null != e.Sender) 488 if (null != e.Sender)
430 DeliverMessage(e.Type, e.Channel, e.Sender.Name, e.Sender.AgentId, e.Message, e.Position); 489 {
490 DeliverMessage(e.Type, e.Channel, e.Sender.Name,
491 e.Sender.AgentId, e.Message, e.Position);
492 }
431 else 493 else
432 DeliverMessage(e.Type, e.Channel, e.From, UUID.Zero, e.Message, e.Position); 494 {
495 DeliverMessage(e.Type, e.Channel, e.From, UUID.Zero,
496 e.Message, e.Position);
497 }
433 } 498 }
434 499
435 public Object[] GetSerializationData(UUID itemID) 500 public Object[] GetSerializationData(UUID itemID)
@@ -446,7 +511,8 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
446 511
447 public class ListenerManager 512 public class ListenerManager
448 { 513 {
449 private Dictionary<int, List<ListenerInfo>> m_listeners = new Dictionary<int, List<ListenerInfo>>(); 514 private Dictionary<int, List<ListenerInfo>> m_listeners =
515 new Dictionary<int, List<ListenerInfo>>();
450 private int m_maxlisteners; 516 private int m_maxlisteners;
451 private int m_maxhandles; 517 private int m_maxhandles;
452 private int m_curlisteners; 518 private int m_curlisteners;
@@ -470,15 +536,25 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
470 m_curlisteners = 0; 536 m_curlisteners = 0;
471 } 537 }
472 538
473 public int AddListener(uint localID, UUID itemID, UUID hostID, int channel, string name, UUID id, string msg) 539 public int AddListener(uint localID, UUID itemID, UUID hostID,
540 int channel, string name, UUID id, string msg)
541 {
542 return AddListener(localID, itemID, hostID, channel, name, id,
543 msg, 0);
544 }
545
546 public int AddListener(uint localID, UUID itemID, UUID hostID,
547 int channel, string name, UUID id, string msg,
548 int regexBitfield)
474 { 549 {
475 // do we already have a match on this particular filter event? 550 // do we already have a match on this particular filter event?
476 List<ListenerInfo> coll = GetListeners(itemID, channel, name, id, msg); 551 List<ListenerInfo> coll = GetListeners(itemID, channel, name, id,
552 msg);
477 553
478 if (coll.Count > 0) 554 if (coll.Count > 0)
479 { 555 {
480 // special case, called with same filter settings, return same handle 556 // special case, called with same filter settings, return same
481 // (2008-05-02, tested on 1.21.1 server, still holds) 557 // handle (2008-05-02, tested on 1.21.1 server, still holds)
482 return coll[0].GetHandle(); 558 return coll[0].GetHandle();
483 } 559 }
484 560
@@ -490,16 +566,19 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
490 566
491 if (newHandle > 0) 567 if (newHandle > 0)
492 { 568 {
493 ListenerInfo li = new ListenerInfo(newHandle, localID, itemID, hostID, channel, name, id, msg); 569 ListenerInfo li = new ListenerInfo(newHandle, localID,
570 itemID, hostID, channel, name, id, msg,
571 regexBitfield);
494 572
495 List<ListenerInfo> listeners; 573 List<ListenerInfo> listeners;
496 if (!m_listeners.TryGetValue(channel,out listeners)) 574 if (!m_listeners.TryGetValue(
497 { 575 channel, out listeners))
498 listeners = new List<ListenerInfo>(); 576 {
499 m_listeners.Add(channel, listeners); 577 listeners = new List<ListenerInfo>();
500 } 578 m_listeners.Add(channel, listeners);
501 listeners.Add(li); 579 }
502 m_curlisteners++; 580 listeners.Add(li);
581 m_curlisteners++;
503 582
504 return newHandle; 583 return newHandle;
505 } 584 }
@@ -512,11 +591,13 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
512 { 591 {
513 lock (m_listeners) 592 lock (m_listeners)
514 { 593 {
515 foreach (KeyValuePair<int,List<ListenerInfo>> lis in m_listeners) 594 foreach (KeyValuePair<int, List<ListenerInfo>> lis
595 in m_listeners)
516 { 596 {
517 foreach (ListenerInfo li in lis.Value) 597 foreach (ListenerInfo li in lis.Value)
518 { 598 {
519 if (li.GetItemID().Equals(itemID) && li.GetHandle().Equals(handle)) 599 if (li.GetItemID().Equals(itemID) &&
600 li.GetHandle().Equals(handle))
520 { 601 {
521 lis.Value.Remove(li); 602 lis.Value.Remove(li);
522 if (lis.Value.Count == 0) 603 if (lis.Value.Count == 0)
@@ -539,13 +620,15 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
539 620
540 lock (m_listeners) 621 lock (m_listeners)
541 { 622 {
542 foreach (KeyValuePair<int,List<ListenerInfo>> lis in m_listeners) 623 foreach (KeyValuePair<int, List<ListenerInfo>> lis
624 in m_listeners)
543 { 625 {
544 foreach (ListenerInfo li in lis.Value) 626 foreach (ListenerInfo li in lis.Value)
545 { 627 {
546 if (li.GetItemID().Equals(itemID)) 628 if (li.GetItemID().Equals(itemID))
547 { 629 {
548 // store them first, else the enumerated bails on us 630 // store them first, else the enumerated bails on
631 // us
549 removedListeners.Add(li); 632 removedListeners.Add(li);
550 } 633 }
551 } 634 }
@@ -572,11 +655,13 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
572 { 655 {
573 lock (m_listeners) 656 lock (m_listeners)
574 { 657 {
575 foreach (KeyValuePair<int,List<ListenerInfo>> lis in m_listeners) 658 foreach (KeyValuePair<int, List<ListenerInfo>> lis
659 in m_listeners)
576 { 660 {
577 foreach (ListenerInfo li in lis.Value) 661 foreach (ListenerInfo li in lis.Value)
578 { 662 {
579 if (li.GetItemID().Equals(itemID) && li.GetHandle() == handle) 663 if (li.GetItemID().Equals(itemID) &&
664 li.GetHandle() == handle)
580 { 665 {
581 li.Activate(); 666 li.Activate();
582 // only one, bail out 667 // only one, bail out
@@ -591,11 +676,13 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
591 { 676 {
592 lock (m_listeners) 677 lock (m_listeners)
593 { 678 {
594 foreach (KeyValuePair<int,List<ListenerInfo>> lis in m_listeners) 679 foreach (KeyValuePair<int, List<ListenerInfo>> lis
680 in m_listeners)
595 { 681 {
596 foreach (ListenerInfo li in lis.Value) 682 foreach (ListenerInfo li in lis.Value)
597 { 683 {
598 if (li.GetItemID().Equals(itemID) && li.GetHandle() == handle) 684 if (li.GetItemID().Equals(itemID) &&
685 li.GetHandle() == handle)
599 { 686 {
600 li.Deactivate(); 687 li.Deactivate();
601 // only one, bail out 688 // only one, bail out
@@ -606,19 +693,24 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
606 } 693 }
607 } 694 }
608 695
609 // non-locked access, since its always called in the context of the lock 696 /// <summary>
697 /// non-locked access, since its always called in the context of the
698 /// lock
699 /// </summary>
700 /// <param name="itemID"></param>
701 /// <returns></returns>
610 private int GetNewHandle(UUID itemID) 702 private int GetNewHandle(UUID itemID)
611 { 703 {
612 List<int> handles = new List<int>(); 704 List<int> handles = new List<int>();
613 705
614 // build a list of used keys for this specific itemID... 706 // build a list of used keys for this specific itemID...
615 foreach (KeyValuePair<int,List<ListenerInfo>> lis in m_listeners) 707 foreach (KeyValuePair<int, List<ListenerInfo>> lis in m_listeners)
616 { 708 {
617 foreach (ListenerInfo li in lis.Value) 709 foreach (ListenerInfo li in lis.Value)
618 { 710 {
619 if (li.GetItemID().Equals(itemID)) 711 if (li.GetItemID().Equals(itemID))
620 handles.Add(li.GetHandle()); 712 handles.Add(li.GetHandle());
621 } 713 }
622 } 714 }
623 715
624 // Note: 0 is NOT a valid handle for llListen() to return 716 // Note: 0 is NOT a valid handle for llListen() to return
@@ -631,17 +723,46 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
631 return -1; 723 return -1;
632 } 724 }
633 725
634 // Theres probably a more clever and efficient way to 726 /// These are duplicated from ScriptBaseClass
635 // do this, maybe with regex. 727 /// http://opensimulator.org/mantis/view.php?id=6106#c21945
636 // PM2008: Ha, one could even be smart and define a specialized Enumerator. 728 #region Constants for the bitfield parameter of osListenRegex
637 public List<ListenerInfo> GetListeners(UUID itemID, int channel, string name, UUID id, string msg) 729
730 /// <summary>
731 /// process name parameter as regex
732 /// </summary>
733 public const int OS_LISTEN_REGEX_NAME = 0x1;
734
735 /// <summary>
736 /// process message parameter as regex
737 /// </summary>
738 public const int OS_LISTEN_REGEX_MESSAGE = 0x2;
739
740 #endregion
741
742 /// <summary>
743 /// Get listeners matching the input parameters.
744 /// </summary>
745 /// <remarks>
746 /// Theres probably a more clever and efficient way to do this, maybe
747 /// with regex.
748 /// PM2008: Ha, one could even be smart and define a specialized
749 /// Enumerator.
750 /// </remarks>
751 /// <param name="itemID"></param>
752 /// <param name="channel"></param>
753 /// <param name="name"></param>
754 /// <param name="id"></param>
755 /// <param name="msg"></param>
756 /// <returns></returns>
757 public List<ListenerInfo> GetListeners(UUID itemID, int channel,
758 string name, UUID id, string msg)
638 { 759 {
639 List<ListenerInfo> collection = new List<ListenerInfo>(); 760 List<ListenerInfo> collection = new List<ListenerInfo>();
640 761
641 lock (m_listeners) 762 lock (m_listeners)
642 { 763 {
643 List<ListenerInfo> listeners; 764 List<ListenerInfo> listeners;
644 if (!m_listeners.TryGetValue(channel,out listeners)) 765 if (!m_listeners.TryGetValue(channel, out listeners))
645 { 766 {
646 return collection; 767 return collection;
647 } 768 }
@@ -652,11 +773,15 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
652 { 773 {
653 continue; 774 continue;
654 } 775 }
655 if (!itemID.Equals(UUID.Zero) && !li.GetItemID().Equals(itemID)) 776 if (!itemID.Equals(UUID.Zero) &&
777 !li.GetItemID().Equals(itemID))
656 { 778 {
657 continue; 779 continue;
658 } 780 }
659 if (li.GetName().Length > 0 && !li.GetName().Equals(name)) 781 if (li.GetName().Length > 0 && (
782 ((li.RegexBitfield & OS_LISTEN_REGEX_NAME) != OS_LISTEN_REGEX_NAME && !li.GetName().Equals(name)) ||
783 ((li.RegexBitfield & OS_LISTEN_REGEX_NAME) == OS_LISTEN_REGEX_NAME && !Regex.IsMatch(name, li.GetName()))
784 ))
660 { 785 {
661 continue; 786 continue;
662 } 787 }
@@ -664,7 +789,10 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
664 { 789 {
665 continue; 790 continue;
666 } 791 }
667 if (li.GetMessage().Length > 0 && !li.GetMessage().Equals(msg)) 792 if (li.GetMessage().Length > 0 && (
793 ((li.RegexBitfield & OS_LISTEN_REGEX_MESSAGE) != OS_LISTEN_REGEX_MESSAGE && !li.GetMessage().Equals(msg)) ||
794 ((li.RegexBitfield & OS_LISTEN_REGEX_MESSAGE) == OS_LISTEN_REGEX_MESSAGE && !Regex.IsMatch(msg, li.GetMessage()))
795 ))
668 { 796 {
669 continue; 797 continue;
670 } 798 }
@@ -697,10 +825,13 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
697 { 825 {
698 int idx = 0; 826 int idx = 0;
699 Object[] item = new Object[6]; 827 Object[] item = new Object[6];
828 int dataItemLength = 6;
700 829
701 while (idx < data.Length) 830 while (idx < data.Length)
702 { 831 {
703 Array.Copy(data, idx, item, 0, 6); 832 dataItemLength = (idx + 7 == data.Length || (idx + 7 < data.Length && data[idx + 7] is bool)) ? 7 : 6;
833 item = new Object[dataItemLength];
834 Array.Copy(data, idx, item, 0, dataItemLength);
704 835
705 ListenerInfo info = 836 ListenerInfo info =
706 ListenerInfo.FromData(localID, itemID, hostID, item); 837 ListenerInfo.FromData(localID, itemID, hostID, item);
@@ -708,39 +839,98 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
708 lock (m_listeners) 839 lock (m_listeners)
709 { 840 {
710 if (!m_listeners.ContainsKey((int)item[2])) 841 if (!m_listeners.ContainsKey((int)item[2]))
711 m_listeners.Add((int)item[2], new List<ListenerInfo>()); 842 {
843 m_listeners.Add((int)item[2],
844 new List<ListenerInfo>());
845 }
712 m_listeners[(int)item[2]].Add(info); 846 m_listeners[(int)item[2]].Add(info);
713 } 847 }
714 848
715 idx+=6; 849 idx += dataItemLength;
716 } 850 }
717 } 851 }
718 } 852 }
719 853
720 public class ListenerInfo: IWorldCommListenerInfo 854 public class ListenerInfo : IWorldCommListenerInfo
721 { 855 {
722 private bool m_active; // Listener is active or not 856 /// <summary>
723 private int m_handle; // Assigned handle of this listener 857 /// Listener is active or not
724 private uint m_localID; // Local ID from script engine 858 /// </summary>
725 private UUID m_itemID; // ID of the host script engine 859 private bool m_active;
726 private UUID m_hostID; // ID of the host/scene part 860
727 private int m_channel; // Channel 861 /// <summary>
728 private UUID m_id; // ID to filter messages from 862 /// Assigned handle of this listener
729 private string m_name; // Object name to filter messages from 863 /// </summary>
730 private string m_message; // The message 864 private int m_handle;
865
866 /// <summary>
867 /// Local ID from script engine
868 /// </summary>
869 private uint m_localID;
870
871 /// <summary>
872 /// ID of the host script engine
873 /// </summary>
874 private UUID m_itemID;
875
876 /// <summary>
877 /// ID of the host/scene part
878 /// </summary>
879 private UUID m_hostID;
880
881 /// <summary>
882 /// Channel
883 /// </summary>
884 private int m_channel;
885
886 /// <summary>
887 /// ID to filter messages from
888 /// </summary>
889 private UUID m_id;
890
891 /// <summary>
892 /// Object name to filter messages from
893 /// </summary>
894 private string m_name;
895
896 /// <summary>
897 /// The message
898 /// </summary>
899 private string m_message;
900
901 public ListenerInfo(int handle, uint localID, UUID ItemID,
902 UUID hostID, int channel, string name, UUID id,
903 string message)
904 {
905 Initialise(handle, localID, ItemID, hostID, channel, name, id,
906 message, 0);
907 }
731 908
732 public ListenerInfo(int handle, uint localID, UUID ItemID, UUID hostID, int channel, string name, UUID id, string message) 909 public ListenerInfo(int handle, uint localID, UUID ItemID,
910 UUID hostID, int channel, string name, UUID id,
911 string message, int regexBitfield)
733 { 912 {
734 Initialise(handle, localID, ItemID, hostID, channel, name, id, message); 913 Initialise(handle, localID, ItemID, hostID, channel, name, id,
914 message, regexBitfield);
735 } 915 }
736 916
737 public ListenerInfo(ListenerInfo li, string name, UUID id, string message) 917 public ListenerInfo(ListenerInfo li, string name, UUID id,
918 string message)
738 { 919 {
739 Initialise(li.m_handle, li.m_localID, li.m_itemID, li.m_hostID, li.m_channel, name, id, message); 920 Initialise(li.m_handle, li.m_localID, li.m_itemID, li.m_hostID,
921 li.m_channel, name, id, message, 0);
740 } 922 }
741 923
742 private void Initialise(int handle, uint localID, UUID ItemID, UUID hostID, int channel, string name, 924 public ListenerInfo(ListenerInfo li, string name, UUID id,
743 UUID id, string message) 925 string message, int regexBitfield)
926 {
927 Initialise(li.m_handle, li.m_localID, li.m_itemID, li.m_hostID,
928 li.m_channel, name, id, message, regexBitfield);
929 }
930
931 private void Initialise(int handle, uint localID, UUID ItemID,
932 UUID hostID, int channel, string name, UUID id,
933 string message, int regexBitfield)
744 { 934 {
745 m_active = true; 935 m_active = true;
746 m_handle = handle; 936 m_handle = handle;
@@ -751,11 +941,12 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
751 m_name = name; 941 m_name = name;
752 m_id = id; 942 m_id = id;
753 m_message = message; 943 m_message = message;
944 RegexBitfield = regexBitfield;
754 } 945 }
755 946
756 public Object[] GetSerializationData() 947 public Object[] GetSerializationData()
757 { 948 {
758 Object[] data = new Object[6]; 949 Object[] data = new Object[7];
759 950
760 data[0] = m_active; 951 data[0] = m_active;
761 data[1] = m_handle; 952 data[1] = m_handle;
@@ -763,16 +954,22 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
763 data[3] = m_name; 954 data[3] = m_name;
764 data[4] = m_id; 955 data[4] = m_id;
765 data[5] = m_message; 956 data[5] = m_message;
957 data[6] = RegexBitfield;
766 958
767 return data; 959 return data;
768 } 960 }
769 961
770 public static ListenerInfo FromData(uint localID, UUID ItemID, UUID hostID, Object[] data) 962 public static ListenerInfo FromData(uint localID, UUID ItemID,
963 UUID hostID, Object[] data)
771 { 964 {
772 ListenerInfo linfo = new ListenerInfo((int)data[1], localID, 965 ListenerInfo linfo = new ListenerInfo((int)data[1], localID,
773 ItemID, hostID, (int)data[2], (string)data[3], 966 ItemID, hostID, (int)data[2], (string)data[3],
774 (UUID)data[4], (string)data[5]); 967 (UUID)data[4], (string)data[5]);
775 linfo.m_active=(bool)data[0]; 968 linfo.m_active = (bool)data[0];
969 if (data.Length >= 7)
970 {
971 linfo.RegexBitfield = (int)data[6];
972 }
776 973
777 return linfo; 974 return linfo;
778 } 975 }
@@ -831,5 +1028,7 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
831 { 1028 {
832 return m_id; 1029 return m_id;
833 } 1030 }
1031
1032 public int RegexBitfield { get; private set; }
834 } 1033 }
835} 1034}