aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs')
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs207
1 files changed, 113 insertions, 94 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs
index 4d2c0f2..9b9f6a7 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs
@@ -59,12 +59,20 @@ namespace OpenSim.Region.ClientStack.Linden
59 public class EventQueueGetModule : IEventQueue, INonSharedRegionModule 59 public class EventQueueGetModule : IEventQueue, INonSharedRegionModule
60 { 60 {
61 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 61 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
62 private static string LogHeader = "[EVENT QUEUE GET MODULE]";
62 63
63 /// <value> 64 /// <value>
64 /// Debug level. 65 /// Debug level.
65 /// </value> 66 /// </value>
66 public int DebugLevel { get; set; } 67 public int DebugLevel { get; set; }
67 68
69 // Viewer post requests timeout in 60 secs
70 // https://bitbucket.org/lindenlab/viewer-release/src/421c20423df93d650cc305dc115922bb30040999/indra/llmessage/llhttpclient.cpp?at=default#cl-44
71 //
72 private const int VIEWER_TIMEOUT = 60 * 1000;
73 // Just to be safe, we work on a 10 sec shorter cycle
74 private const int SERVER_EQ_TIME_NO_EVENTS = VIEWER_TIMEOUT - (10 * 1000);
75
68 protected Scene m_scene; 76 protected Scene m_scene;
69 77
70 private Dictionary<UUID, int> m_ids = new Dictionary<UUID, int>(); 78 private Dictionary<UUID, int> m_ids = new Dictionary<UUID, int>();
@@ -84,7 +92,6 @@ namespace OpenSim.Region.ClientStack.Linden
84 scene.RegisterModuleInterface<IEventQueue>(this); 92 scene.RegisterModuleInterface<IEventQueue>(this);
85 93
86 scene.EventManager.OnClientClosed += ClientClosed; 94 scene.EventManager.OnClientClosed += ClientClosed;
87 scene.EventManager.OnMakeChildAgent += MakeChildAgent;
88 scene.EventManager.OnRegisterCaps += OnRegisterCaps; 95 scene.EventManager.OnRegisterCaps += OnRegisterCaps;
89 96
90 MainConsole.Instance.Commands.AddCommand( 97 MainConsole.Instance.Commands.AddCommand(
@@ -94,9 +101,17 @@ namespace OpenSim.Region.ClientStack.Linden
94 "debug eq [0|1|2]", 101 "debug eq [0|1|2]",
95 "Turn on event queue debugging\n" 102 "Turn on event queue debugging\n"
96 + " <= 0 - turns off all event queue logging\n" 103 + " <= 0 - turns off all event queue logging\n"
97 + " >= 1 - turns on outgoing event logging\n" 104 + " >= 1 - turns on event queue setup and outgoing event logging\n"
98 + " >= 2 - turns on poll notification", 105 + " >= 2 - turns on poll notification",
99 HandleDebugEq); 106 HandleDebugEq);
107
108 MainConsole.Instance.Commands.AddCommand(
109 "Debug",
110 false,
111 "show eq",
112 "show eq",
113 "Show contents of event queues for logged in avatars. Used for debugging.",
114 HandleShowEq);
100 } 115 }
101 116
102 public void RemoveRegion(Scene scene) 117 public void RemoveRegion(Scene scene)
@@ -105,7 +120,6 @@ namespace OpenSim.Region.ClientStack.Linden
105 return; 120 return;
106 121
107 scene.EventManager.OnClientClosed -= ClientClosed; 122 scene.EventManager.OnClientClosed -= ClientClosed;
108 scene.EventManager.OnMakeChildAgent -= MakeChildAgent;
109 scene.EventManager.OnRegisterCaps -= OnRegisterCaps; 123 scene.EventManager.OnRegisterCaps -= OnRegisterCaps;
110 124
111 scene.UnregisterModuleInterface<IEventQueue>(this); 125 scene.UnregisterModuleInterface<IEventQueue>(this);
@@ -138,7 +152,7 @@ namespace OpenSim.Region.ClientStack.Linden
138 152
139 if (!(args.Length == 3 && int.TryParse(args[2], out debugLevel))) 153 if (!(args.Length == 3 && int.TryParse(args[2], out debugLevel)))
140 { 154 {
141 MainConsole.Instance.OutputFormat("Usage: debug eq [0|1]"); 155 MainConsole.Instance.OutputFormat("Usage: debug eq [0|1|2]");
142 } 156 }
143 else 157 else
144 { 158 {
@@ -148,6 +162,21 @@ namespace OpenSim.Region.ClientStack.Linden
148 } 162 }
149 } 163 }
150 164
165 protected void HandleShowEq(string module, string[] args)
166 {
167 MainConsole.Instance.OutputFormat("For scene {0}", m_scene.Name);
168
169 lock (queues)
170 {
171 foreach (KeyValuePair<UUID, Queue<OSD>> kvp in queues)
172 {
173 MainConsole.Instance.OutputFormat(
174 "For agent {0} there are {1} messages queued for send.",
175 kvp.Key, kvp.Value.Count);
176 }
177 }
178 }
179
151 /// <summary> 180 /// <summary>
152 /// Always returns a valid queue 181 /// Always returns a valid queue
153 /// </summary> 182 /// </summary>
@@ -159,14 +188,14 @@ namespace OpenSim.Region.ClientStack.Linden
159 { 188 {
160 if (!queues.ContainsKey(agentId)) 189 if (!queues.ContainsKey(agentId))
161 { 190 {
162 /* 191 if (DebugLevel > 0)
163 m_log.DebugFormat( 192 m_log.DebugFormat(
164 "[EVENTQUEUE]: Adding new queue for agent {0} in region {1}", 193 "[EVENTQUEUE]: Adding new queue for agent {0} in region {1}",
165 agentId, m_scene.RegionInfo.RegionName); 194 agentId, m_scene.RegionInfo.RegionName);
166 */ 195
167 queues[agentId] = new Queue<OSD>(); 196 queues[agentId] = new Queue<OSD>();
168 } 197 }
169 198
170 return queues[agentId]; 199 return queues[agentId];
171 } 200 }
172 } 201 }
@@ -198,8 +227,23 @@ namespace OpenSim.Region.ClientStack.Linden
198 { 227 {
199 Queue<OSD> queue = GetQueue(avatarID); 228 Queue<OSD> queue = GetQueue(avatarID);
200 if (queue != null) 229 if (queue != null)
230 {
201 lock (queue) 231 lock (queue)
202 queue.Enqueue(ev); 232 queue.Enqueue(ev);
233 }
234 else if (DebugLevel > 0)
235 {
236 ScenePresence sp = m_scene.GetScenePresence(avatarID);
237
238 // This assumes that an NPC should never have a queue.
239 if (sp != null && sp.PresenceType != PresenceType.Npc)
240 {
241 OSDMap evMap = (OSDMap)ev;
242 m_log.WarnFormat(
243 "[EVENTQUEUE]: (Enqueue) No queue found for agent {0} {1} when placing message {2} in region {3}",
244 sp.Name, sp.UUID, evMap["message"], m_scene.Name);
245 }
246 }
203 } 247 }
204 catch (NullReferenceException e) 248 catch (NullReferenceException e)
205 { 249 {
@@ -214,44 +258,14 @@ namespace OpenSim.Region.ClientStack.Linden
214 258
215 private void ClientClosed(UUID agentID, Scene scene) 259 private void ClientClosed(UUID agentID, Scene scene)
216 { 260 {
217// m_log.DebugFormat("[EVENTQUEUE]: Closed client {0} in region {1}", agentID, m_scene.RegionInfo.RegionName); 261 //m_log.DebugFormat("[EVENTQUEUE]: Closed client {0} in region {1}", agentID, m_scene.RegionInfo.RegionName);
218
219 int count = 0;
220 while (queues.ContainsKey(agentID) && queues[agentID].Count > 0 && count++ < 5)
221 {
222 Thread.Sleep(1000);
223 }
224 262
225 lock (queues) 263 lock (queues)
226 {
227 queues.Remove(agentID); 264 queues.Remove(agentID);
228 }
229 265
230 List<UUID> removeitems = new List<UUID>(); 266 List<UUID> removeitems = new List<UUID>();
231 lock (m_AvatarQueueUUIDMapping) 267 lock (m_AvatarQueueUUIDMapping)
232 { 268 m_AvatarQueueUUIDMapping.Remove(agentID);
233 foreach (UUID ky in m_AvatarQueueUUIDMapping.Keys)
234 {
235// m_log.DebugFormat("[EVENTQUEUE]: Found key {0} in m_AvatarQueueUUIDMapping while looking for {1}", ky, AgentID);
236 if (ky == agentID)
237 {
238 removeitems.Add(ky);
239 }
240 }
241
242 foreach (UUID ky in removeitems)
243 {
244 UUID eventQueueGetUuid = m_AvatarQueueUUIDMapping[ky];
245 m_AvatarQueueUUIDMapping.Remove(ky);
246
247 string eqgPath = GenerateEqgCapPath(eventQueueGetUuid);
248 MainServer.Instance.RemovePollServiceHTTPHandler("", eqgPath);
249
250// m_log.DebugFormat(
251// "[EVENT QUEUE GET MODULE]: Removed EQG handler {0} for {1} in {2}",
252// eqgPath, agentID, m_scene.RegionInfo.RegionName);
253 }
254 }
255 269
256 UUID searchval = UUID.Zero; 270 UUID searchval = UUID.Zero;
257 271
@@ -272,19 +286,9 @@ namespace OpenSim.Region.ClientStack.Linden
272 foreach (UUID ky in removeitems) 286 foreach (UUID ky in removeitems)
273 m_QueueUUIDAvatarMapping.Remove(ky); 287 m_QueueUUIDAvatarMapping.Remove(ky);
274 } 288 }
275 }
276 289
277 private void MakeChildAgent(ScenePresence avatar) 290 // m_log.DebugFormat("[EVENTQUEUE]: Deleted queues for {0} in region {1}", agentID, m_scene.RegionInfo.RegionName);
278 { 291
279 //m_log.DebugFormat("[EVENTQUEUE]: Make Child agent {0} in region {1}.", avatar.UUID, m_scene.RegionInfo.RegionName);
280 //lock (m_ids)
281 // {
282 //if (m_ids.ContainsKey(avatar.UUID))
283 //{
284 // close the event queue.
285 //m_ids[avatar.UUID] = -1;
286 //}
287 //}
288 } 292 }
289 293
290 /// <summary> 294 /// <summary>
@@ -300,9 +304,10 @@ namespace OpenSim.Region.ClientStack.Linden
300 { 304 {
301 // Register an event queue for the client 305 // Register an event queue for the client
302 306
303 //m_log.DebugFormat( 307 if (DebugLevel > 0)
304 // "[EVENTQUEUE]: OnRegisterCaps: agentID {0} caps {1} region {2}", 308 m_log.DebugFormat(
305 // agentID, caps, m_scene.RegionInfo.RegionName); 309 "[EVENTQUEUE]: OnRegisterCaps: agentID {0} caps {1} region {2}",
310 agentID, caps, m_scene.RegionInfo.RegionName);
306 311
307 // Let's instantiate a Queue for this agent right now 312 // Let's instantiate a Queue for this agent right now
308 TryGetQueue(agentID); 313 TryGetQueue(agentID);
@@ -336,28 +341,9 @@ namespace OpenSim.Region.ClientStack.Linden
336 m_AvatarQueueUUIDMapping.Add(agentID, eventQueueGetUUID); 341 m_AvatarQueueUUIDMapping.Add(agentID, eventQueueGetUUID);
337 } 342 }
338 343
339 string eventQueueGetPath = GenerateEqgCapPath(eventQueueGetUUID); 344 caps.RegisterPollHandler(
340 345 "EventQueueGet",
341 // Register this as a caps handler 346 new PollServiceEventArgs(null, GenerateEqgCapPath(eventQueueGetUUID), HasEvents, GetEvents, NoEvents, agentID, SERVER_EQ_TIME_NO_EVENTS));
342 // FIXME: Confusingly, we need to register separate as a capability so that the client is told about
343 // EventQueueGet when it receive capability information, but then we replace the rest handler immediately
344 // afterwards with the poll service. So for now, we'll pass a null instead to simplify code reading, but
345 // really it should be possible to directly register the poll handler as a capability.
346 caps.RegisterHandler("EventQueueGet", new RestHTTPHandler("POST", eventQueueGetPath, null));
347// delegate(Hashtable m_dhttpMethod)
348// {
349// return ProcessQueue(m_dhttpMethod, agentID, caps);
350// }));
351
352 // This will persist this beyond the expiry of the caps handlers
353 // TODO: Add EventQueueGet name/description for diagnostics
354 MainServer.Instance.AddPollServiceHTTPHandler(
355 eventQueueGetPath,
356 new PollServiceEventArgs(null, HasEvents, GetEvents, NoEvents, agentID));
357
358// m_log.DebugFormat(
359// "[EVENT QUEUE GET MODULE]: Registered EQG handler {0} for {1} in {2}",
360// eventQueueGetPath, agentID, m_scene.RegionInfo.RegionName);
361 347
362 Random rnd = new Random(Environment.TickCount); 348 Random rnd = new Random(Environment.TickCount);
363 lock (m_ids) 349 lock (m_ids)
@@ -375,7 +361,10 @@ namespace OpenSim.Region.ClientStack.Linden
375 Queue<OSD> queue = GetQueue(agentID); 361 Queue<OSD> queue = GetQueue(agentID);
376 if (queue != null) 362 if (queue != null)
377 lock (queue) 363 lock (queue)
364 {
365 //m_log.WarnFormat("POLLED FOR EVENTS BY {0} in {1} -- {2}", agentID, m_scene.RegionInfo.RegionName, queue.Count);
378 return queue.Count > 0; 366 return queue.Count > 0;
367 }
379 368
380 return false; 369 return false;
381 } 370 }
@@ -391,16 +380,21 @@ namespace OpenSim.Region.ClientStack.Linden
391 OSDMap ev = (OSDMap)element; 380 OSDMap ev = (OSDMap)element;
392 m_log.DebugFormat( 381 m_log.DebugFormat(
393 "Eq OUT {0,-30} to {1,-20} {2,-20}", 382 "Eq OUT {0,-30} to {1,-20} {2,-20}",
394 ev["message"], m_scene.GetScenePresence(agentId).Name, m_scene.RegionInfo.RegionName); 383 ev["message"], m_scene.GetScenePresence(agentId).Name, m_scene.Name);
395 } 384 }
396 } 385 }
397 386
398 public Hashtable GetEvents(UUID requestID, UUID pAgentId, string request) 387 public Hashtable GetEvents(UUID requestID, UUID pAgentId)
399 { 388 {
400 if (DebugLevel >= 2) 389 if (DebugLevel >= 2)
401 m_log.DebugFormat("POLLED FOR EQ MESSAGES BY {0} in {1}", pAgentId, m_scene.RegionInfo.RegionName); 390 m_log.WarnFormat("POLLED FOR EQ MESSAGES BY {0} in {1}", pAgentId, m_scene.Name);
391
392 Queue<OSD> queue = GetQueue(pAgentId);
393 if (queue == null)
394 {
395 return NoEvents(requestID, pAgentId);
396 }
402 397
403 Queue<OSD> queue = TryGetQueue(pAgentId);
404 OSD element; 398 OSD element;
405 lock (queue) 399 lock (queue)
406 { 400 {
@@ -727,34 +721,51 @@ namespace OpenSim.Region.ClientStack.Linden
727 Enqueue(item, avatarID); 721 Enqueue(item, avatarID);
728 } 722 }
729 723
730 public virtual void EnableSimulator(ulong handle, IPEndPoint endPoint, UUID avatarID) 724 public virtual void EnableSimulator(ulong handle, IPEndPoint endPoint, UUID avatarID, int regionSizeX, int regionSizeY)
731 { 725 {
732 OSD item = EventQueueHelper.EnableSimulator(handle, endPoint); 726 if (DebugLevel > 0)
727 m_log.DebugFormat("{0} EnableSimulator. handle={1}, endPoint={2}, avatarID={3}",
728 LogHeader, handle, endPoint, avatarID, regionSizeX, regionSizeY);
729
730 OSD item = EventQueueHelper.EnableSimulator(handle, endPoint, regionSizeX, regionSizeY);
733 Enqueue(item, avatarID); 731 Enqueue(item, avatarID);
734 } 732 }
735 733
736 public virtual void EstablishAgentCommunication(UUID avatarID, IPEndPoint endPoint, string capsPath) 734 public virtual void EstablishAgentCommunication(UUID avatarID, IPEndPoint endPoint, string capsPath,
735 ulong regionHandle, int regionSizeX, int regionSizeY)
737 { 736 {
738 OSD item = EventQueueHelper.EstablishAgentCommunication(avatarID, endPoint.ToString(), capsPath); 737 if (DebugLevel > 0)
738 m_log.DebugFormat("{0} EstablishAgentCommunication. handle={1}, endPoint={2}, avatarID={3}",
739 LogHeader, regionHandle, endPoint, avatarID, regionSizeX, regionSizeY);
740
741 OSD item = EventQueueHelper.EstablishAgentCommunication(avatarID, endPoint.ToString(), capsPath, regionHandle, regionSizeX, regionSizeY);
739 Enqueue(item, avatarID); 742 Enqueue(item, avatarID);
740 } 743 }
741 744
742 public virtual void TeleportFinishEvent(ulong regionHandle, byte simAccess, 745 public virtual void TeleportFinishEvent(ulong regionHandle, byte simAccess,
743 IPEndPoint regionExternalEndPoint, 746 IPEndPoint regionExternalEndPoint,
744 uint locationID, uint flags, string capsURL, 747 uint locationID, uint flags, string capsURL,
745 UUID avatarID) 748 UUID avatarID, int regionSizeX, int regionSizeY)
746 { 749 {
750 if (DebugLevel > 0)
751 m_log.DebugFormat("{0} TeleportFinishEvent. handle={1}, endPoint={2}, avatarID={3}",
752 LogHeader, regionHandle, regionExternalEndPoint, avatarID, regionSizeX, regionSizeY);
753
747 OSD item = EventQueueHelper.TeleportFinishEvent(regionHandle, simAccess, regionExternalEndPoint, 754 OSD item = EventQueueHelper.TeleportFinishEvent(regionHandle, simAccess, regionExternalEndPoint,
748 locationID, flags, capsURL, avatarID); 755 locationID, flags, capsURL, avatarID, regionSizeX, regionSizeY);
749 Enqueue(item, avatarID); 756 Enqueue(item, avatarID);
750 } 757 }
751 758
752 public virtual void CrossRegion(ulong handle, Vector3 pos, Vector3 lookAt, 759 public virtual void CrossRegion(ulong handle, Vector3 pos, Vector3 lookAt,
753 IPEndPoint newRegionExternalEndPoint, 760 IPEndPoint newRegionExternalEndPoint,
754 string capsURL, UUID avatarID, UUID sessionID) 761 string capsURL, UUID avatarID, UUID sessionID, int regionSizeX, int regionSizeY)
755 { 762 {
763 if (DebugLevel > 0)
764 m_log.DebugFormat("{0} CrossRegion. handle={1}, avatarID={2}, regionSize={3},{4}>",
765 LogHeader, handle, avatarID, regionSizeX, regionSizeY);
766
756 OSD item = EventQueueHelper.CrossRegion(handle, pos, lookAt, newRegionExternalEndPoint, 767 OSD item = EventQueueHelper.CrossRegion(handle, pos, lookAt, newRegionExternalEndPoint,
757 capsURL, avatarID, sessionID); 768 capsURL, avatarID, sessionID, regionSizeX, regionSizeY);
758 Enqueue(item, avatarID); 769 Enqueue(item, avatarID);
759 } 770 }
760 771
@@ -771,12 +782,12 @@ namespace OpenSim.Region.ClientStack.Linden
771 782
772 } 783 }
773 784
774 public void ChatterBoxSessionAgentListUpdates(UUID sessionID, UUID fromAgent, UUID toAgent, bool canVoiceChat, 785 public void ChatterBoxSessionAgentListUpdates(UUID sessionID, UUID fromAgent, UUID anotherAgent, bool canVoiceChat,
775 bool isModerator, bool textMute) 786 bool isModerator, bool textMute)
776 { 787 {
777 OSD item = EventQueueHelper.ChatterBoxSessionAgentListUpdates(sessionID, fromAgent, canVoiceChat, 788 OSD item = EventQueueHelper.ChatterBoxSessionAgentListUpdates(sessionID, fromAgent, canVoiceChat,
778 isModerator, textMute); 789 isModerator, textMute);
779 Enqueue(item, toAgent); 790 Enqueue(item, fromAgent);
780 //m_log.InfoFormat("########### eq ChatterBoxSessionAgentListUpdates #############\n{0}", item); 791 //m_log.InfoFormat("########### eq ChatterBoxSessionAgentListUpdates #############\n{0}", item);
781 } 792 }
782 793
@@ -807,5 +818,13 @@ namespace OpenSim.Region.ClientStack.Linden
807 { 818 {
808 return EventQueueHelper.BuildEvent(eventName, eventBody); 819 return EventQueueHelper.BuildEvent(eventName, eventBody);
809 } 820 }
821
822 public void partPhysicsProperties(uint localID, byte physhapetype,
823 float density, float friction, float bounce, float gravmod,UUID avatarID)
824 {
825 OSD item = EventQueueHelper.partPhysicsProperties(localID, physhapetype,
826 density, friction, bounce, gravmod);
827 Enqueue(item, avatarID);
828 }
810 } 829 }
811} 830} \ No newline at end of file