diff options
Diffstat (limited to 'OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs')
-rw-r--r-- | OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs | 375 |
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 @@ | |||
28 | using System; | 28 | using System; |
29 | using System.Collections; | 29 | using System.Collections; |
30 | using System.Collections.Generic; | 30 | using System.Collections.Generic; |
31 | using System.Text.RegularExpressions; | ||
32 | |||
31 | using Nini.Config; | 33 | using Nini.Config; |
34 | using Mono.Addins; | ||
35 | |||
32 | using OpenMetaverse; | 36 | using OpenMetaverse; |
37 | |||
33 | using OpenSim.Framework; | 38 | using OpenSim.Framework; |
34 | using OpenSim.Region.Framework.Interfaces; | 39 | using OpenSim.Region.Framework.Interfaces; |
35 | using OpenSim.Region.Framework.Scenes; | 40 | using OpenSim.Region.Framework.Scenes; |
@@ -85,7 +90,8 @@ using OpenSim.Region.Framework.Scenes; | |||
85 | 90 | ||
86 | namespace OpenSim.Region.CoreModules.Scripting.WorldComm | 91 | namespace 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 | } |