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.cs618
1 files changed, 178 insertions, 440 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs
index eb40eb1..ca6c3ca 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs
@@ -65,12 +65,18 @@ namespace OpenSim.Region.ClientStack.Linden
65 /// </value> 65 /// </value>
66 public int DebugLevel { get; set; } 66 public int DebugLevel { get; set; }
67 67
68 // Viewer post requests timeout in 60 secs
69 // https://bitbucket.org/lindenlab/viewer-release/src/421c20423df93d650cc305dc115922bb30040999/indra/llmessage/llhttpclient.cpp?at=default#cl-44
70 //
71 private const int VIEWER_TIMEOUT = 60 * 1000;
72 // Just to be safe, we work on a 10 sec shorter cycle
73 private const int SERVER_EQ_TIME_NO_EVENTS = VIEWER_TIMEOUT - (10 * 1000);
74
68 protected Scene m_scene; 75 protected Scene m_scene;
69 76
70 private Dictionary<UUID, int> m_ids = new Dictionary<UUID, int>(); 77 private Dictionary<UUID, int> m_ids = new Dictionary<UUID, int>();
71 78
72 private Dictionary<UUID, Queue<OSD>> queues = new Dictionary<UUID, Queue<OSD>>(); 79 private Dictionary<UUID, Queue<OSD>> queues = new Dictionary<UUID, Queue<OSD>>();
73 private Dictionary<UUID, UUID> m_QueueUUIDAvatarMapping = new Dictionary<UUID, UUID>();
74 private Dictionary<UUID, UUID> m_AvatarQueueUUIDMapping = new Dictionary<UUID, UUID>(); 80 private Dictionary<UUID, UUID> m_AvatarQueueUUIDMapping = new Dictionary<UUID, UUID>();
75 81
76 #region INonSharedRegionModule methods 82 #region INonSharedRegionModule methods
@@ -84,7 +90,6 @@ namespace OpenSim.Region.ClientStack.Linden
84 scene.RegisterModuleInterface<IEventQueue>(this); 90 scene.RegisterModuleInterface<IEventQueue>(this);
85 91
86 scene.EventManager.OnClientClosed += ClientClosed; 92 scene.EventManager.OnClientClosed += ClientClosed;
87 scene.EventManager.OnMakeChildAgent += MakeChildAgent;
88 scene.EventManager.OnRegisterCaps += OnRegisterCaps; 93 scene.EventManager.OnRegisterCaps += OnRegisterCaps;
89 94
90 MainConsole.Instance.Commands.AddCommand( 95 MainConsole.Instance.Commands.AddCommand(
@@ -113,7 +118,6 @@ namespace OpenSim.Region.ClientStack.Linden
113 return; 118 return;
114 119
115 scene.EventManager.OnClientClosed -= ClientClosed; 120 scene.EventManager.OnClientClosed -= ClientClosed;
116 scene.EventManager.OnMakeChildAgent -= MakeChildAgent;
117 scene.EventManager.OnRegisterCaps -= OnRegisterCaps; 121 scene.EventManager.OnRegisterCaps -= OnRegisterCaps;
118 122
119 scene.UnregisterModuleInterface<IEventQueue>(this); 123 scene.UnregisterModuleInterface<IEventQueue>(this);
@@ -172,29 +176,6 @@ namespace OpenSim.Region.ClientStack.Linden
172 } 176 }
173 177
174 /// <summary> 178 /// <summary>
175 /// Always returns a valid queue
176 /// </summary>
177 /// <param name="agentId"></param>
178 /// <returns></returns>
179 private Queue<OSD> TryGetQueue(UUID agentId)
180 {
181 lock (queues)
182 {
183 if (!queues.ContainsKey(agentId))
184 {
185 /*
186 m_log.DebugFormat(
187 "[EVENTQUEUE]: Adding new queue for agent {0} in region {1}",
188 agentId, m_scene.RegionInfo.RegionName);
189 */
190 queues[agentId] = new Queue<OSD>();
191 }
192
193 return queues[agentId];
194 }
195 }
196
197 /// <summary>
198 /// May return a null queue 179 /// May return a null queue
199 /// </summary> 180 /// </summary>
200 /// <param name="agentId"></param> 181 /// <param name="agentId"></param>
@@ -221,8 +202,17 @@ namespace OpenSim.Region.ClientStack.Linden
221 { 202 {
222 Queue<OSD> queue = GetQueue(avatarID); 203 Queue<OSD> queue = GetQueue(avatarID);
223 if (queue != null) 204 if (queue != null)
205 {
224 lock (queue) 206 lock (queue)
225 queue.Enqueue(ev); 207 queue.Enqueue(ev);
208 }
209 else
210 {
211 OSDMap evMap = (OSDMap)ev;
212 m_log.WarnFormat(
213 "[EVENTQUEUE]: (Enqueue) No queue found for agent {0} when placing message {1} in region {2}",
214 avatarID, evMap["message"], m_scene.Name);
215 }
226 } 216 }
227 catch (NullReferenceException e) 217 catch (NullReferenceException e)
228 { 218 {
@@ -237,77 +227,22 @@ namespace OpenSim.Region.ClientStack.Linden
237 227
238 private void ClientClosed(UUID agentID, Scene scene) 228 private void ClientClosed(UUID agentID, Scene scene)
239 { 229 {
240// m_log.DebugFormat("[EVENTQUEUE]: Closed client {0} in region {1}", agentID, m_scene.RegionInfo.RegionName); 230 //m_log.DebugFormat("[EVENTQUEUE]: Closed client {0} in region {1}", agentID, m_scene.RegionInfo.RegionName);
241
242 int count = 0;
243 while (queues.ContainsKey(agentID) && queues[agentID].Count > 0 && count++ < 5)
244 {
245 Thread.Sleep(1000);
246 }
247 231
248 lock (queues) 232 lock (queues)
249 {
250 queues.Remove(agentID); 233 queues.Remove(agentID);
251 }
252 234
253 List<UUID> removeitems = new List<UUID>();
254 lock (m_AvatarQueueUUIDMapping) 235 lock (m_AvatarQueueUUIDMapping)
255 { 236 m_AvatarQueueUUIDMapping.Remove(agentID);
256 foreach (UUID ky in m_AvatarQueueUUIDMapping.Keys)
257 {
258// m_log.DebugFormat("[EVENTQUEUE]: Found key {0} in m_AvatarQueueUUIDMapping while looking for {1}", ky, AgentID);
259 if (ky == agentID)
260 {
261 removeitems.Add(ky);
262 }
263 }
264
265 foreach (UUID ky in removeitems)
266 {
267 UUID eventQueueGetUuid = m_AvatarQueueUUIDMapping[ky];
268 m_AvatarQueueUUIDMapping.Remove(ky);
269 237
270 string eqgPath = GenerateEqgCapPath(eventQueueGetUuid); 238 lock (m_ids)
271 MainServer.Instance.RemovePollServiceHTTPHandler("", eqgPath);
272
273// m_log.DebugFormat(
274// "[EVENT QUEUE GET MODULE]: Removed EQG handler {0} for {1} in {2}",
275// eqgPath, agentID, m_scene.RegionInfo.RegionName);
276 }
277 }
278
279 UUID searchval = UUID.Zero;
280
281 removeitems.Clear();
282
283 lock (m_QueueUUIDAvatarMapping)
284 { 239 {
285 foreach (UUID ky in m_QueueUUIDAvatarMapping.Keys) 240 if (!m_ids.ContainsKey(agentID))
286 { 241 m_ids.Remove(agentID);
287 searchval = m_QueueUUIDAvatarMapping[ky];
288
289 if (searchval == agentID)
290 {
291 removeitems.Add(ky);
292 }
293 }
294
295 foreach (UUID ky in removeitems)
296 m_QueueUUIDAvatarMapping.Remove(ky);
297 } 242 }
298 }
299 243
300 private void MakeChildAgent(ScenePresence avatar) 244 // m_log.DebugFormat("[EVENTQUEUE]: Deleted queues for {0} in region {1}", agentID, m_scene.RegionInfo.RegionName);
301 { 245
302 //m_log.DebugFormat("[EVENTQUEUE]: Make Child agent {0} in region {1}.", avatar.UUID, m_scene.RegionInfo.RegionName);
303 //lock (m_ids)
304 // {
305 //if (m_ids.ContainsKey(avatar.UUID))
306 //{
307 // close the event queue.
308 //m_ids[avatar.UUID] = -1;
309 //}
310 //}
311 } 246 }
312 247
313 /// <summary> 248 /// <summary>
@@ -322,85 +257,109 @@ namespace OpenSim.Region.ClientStack.Linden
322 public void OnRegisterCaps(UUID agentID, Caps caps) 257 public void OnRegisterCaps(UUID agentID, Caps caps)
323 { 258 {
324 // Register an event queue for the client 259 // Register an event queue for the client
325 260 m_log.DebugFormat(
326 //m_log.DebugFormat( 261 "[EVENTQUEUE]: OnRegisterCaps: agentID {0} caps {1} region {2}",
327 // "[EVENTQUEUE]: OnRegisterCaps: agentID {0} caps {1} region {2}", 262 agentID, caps, m_scene.RegionInfo.RegionName);
328 // agentID, caps, m_scene.RegionInfo.RegionName);
329
330 // Let's instantiate a Queue for this agent right now
331 TryGetQueue(agentID);
332 263
333 UUID eventQueueGetUUID; 264 UUID eventQueueGetUUID;
265 Queue<OSD> queue;
266 Random rnd = new Random(Environment.TickCount);
267 int nrnd = rnd.Next(30000000);
268 if (nrnd < 0)
269 nrnd = -nrnd;
334 270
335 lock (m_AvatarQueueUUIDMapping) 271 lock (queues)
336 { 272 {
337 // Reuse open queues. The client does! 273 if (queues.ContainsKey(agentID))
338 if (m_AvatarQueueUUIDMapping.ContainsKey(agentID)) 274 queue = queues[agentID];
275 else
276 queue = null;
277
278 if (queue == null)
339 { 279 {
340 //m_log.DebugFormat("[EVENTQUEUE]: Found Existing UUID!"); 280 queue = new Queue<OSD>();
341 eventQueueGetUUID = m_AvatarQueueUUIDMapping[agentID]; 281 queues[agentID] = queue;
282
283 // push markers to handle old responses still waiting
284 // this will cost at most viewer getting two forced noevents
285 // even being a new queue better be safe
286 queue.Enqueue(null);
287 queue.Enqueue(null); // one should be enough
288
289 lock (m_AvatarQueueUUIDMapping)
290 {
291 eventQueueGetUUID = UUID.Random();
292 if (m_AvatarQueueUUIDMapping.ContainsKey(agentID))
293 {
294 // oops this should not happen ?
295 m_log.DebugFormat("[EVENTQUEUE]: Found Existing UUID without a queue");
296 eventQueueGetUUID = m_AvatarQueueUUIDMapping[agentID];
297 }
298 m_AvatarQueueUUIDMapping.Add(agentID, eventQueueGetUUID);
299 }
300 lock (m_ids)
301 {
302 if (!m_ids.ContainsKey(agentID))
303 m_ids.Add(agentID, nrnd);
304 else
305 m_ids[agentID] = nrnd;
306 }
342 } 307 }
343 else 308 else
344 { 309 {
345 eventQueueGetUUID = UUID.Random(); 310 // push markers to handle old responses still waiting
346 //m_log.DebugFormat("[EVENTQUEUE]: Using random UUID!"); 311 // this will cost at most viewer getting two forced noevents
312 // even being a new queue better be safe
313 queue.Enqueue(null);
314 queue.Enqueue(null); // one should be enough
315
316 // reuse or not to reuse TODO FIX
317 lock (m_AvatarQueueUUIDMapping)
318 {
319 // Reuse open queues. The client does!
320 // Its reuse caps path not queues those are been reused already
321 if (m_AvatarQueueUUIDMapping.ContainsKey(agentID))
322 {
323 m_log.DebugFormat("[EVENTQUEUE]: Found Existing UUID!");
324 eventQueueGetUUID = m_AvatarQueueUUIDMapping[agentID];
325 }
326 else
327 {
328 eventQueueGetUUID = UUID.Random();
329 m_AvatarQueueUUIDMapping.Add(agentID, eventQueueGetUUID);
330 m_log.DebugFormat("[EVENTQUEUE]: Using random UUID!");
331 }
332 }
333 lock (m_ids)
334 {
335 // change to negative numbers so they are changed at end of sending first marker
336 // old data on a queue may be sent on a response for a new caps
337 // but at least will be sent with coerent IDs
338 if (!m_ids.ContainsKey(agentID))
339 m_ids.Add(agentID, -nrnd); // should not happen
340 else
341 m_ids[agentID] = -m_ids[agentID];
342 }
347 } 343 }
348 } 344 }
349 345
350 lock (m_QueueUUIDAvatarMapping) 346 caps.RegisterPollHandler(
351 { 347 "EventQueueGet",
352 if (!m_QueueUUIDAvatarMapping.ContainsKey(eventQueueGetUUID)) 348 new PollServiceEventArgs(null, GenerateEqgCapPath(eventQueueGetUUID), HasEvents, GetEvents, NoEvents, agentID, SERVER_EQ_TIME_NO_EVENTS));
353 m_QueueUUIDAvatarMapping.Add(eventQueueGetUUID, agentID);
354 }
355
356 lock (m_AvatarQueueUUIDMapping)
357 {
358 if (!m_AvatarQueueUUIDMapping.ContainsKey(agentID))
359 m_AvatarQueueUUIDMapping.Add(agentID, eventQueueGetUUID);
360 }
361
362 string eventQueueGetPath = GenerateEqgCapPath(eventQueueGetUUID);
363
364 // Register this as a caps handler
365 // FIXME: Confusingly, we need to register separate as a capability so that the client is told about
366 // EventQueueGet when it receive capability information, but then we replace the rest handler immediately
367 // afterwards with the poll service. So for now, we'll pass a null instead to simplify code reading, but
368 // really it should be possible to directly register the poll handler as a capability.
369 caps.RegisterHandler("EventQueueGet", new RestHTTPHandler("POST", eventQueueGetPath, null));
370// delegate(Hashtable m_dhttpMethod)
371// {
372// return ProcessQueue(m_dhttpMethod, agentID, caps);
373// }));
374
375 // This will persist this beyond the expiry of the caps handlers
376 // TODO: Add EventQueueGet name/description for diagnostics
377 MainServer.Instance.AddPollServiceHTTPHandler(
378 eventQueueGetPath,
379 new PollServiceEventArgs(null, HasEvents, GetEvents, NoEvents, agentID, 40000));
380
381// m_log.DebugFormat(
382// "[EVENT QUEUE GET MODULE]: Registered EQG handler {0} for {1} in {2}",
383// eventQueueGetPath, agentID, m_scene.RegionInfo.RegionName);
384
385 Random rnd = new Random(Environment.TickCount);
386 lock (m_ids)
387 {
388 if (!m_ids.ContainsKey(agentID))
389 m_ids.Add(agentID, rnd.Next(30000000));
390 }
391 } 349 }
392 350
393 public bool HasEvents(UUID requestID, UUID agentID) 351 public bool HasEvents(UUID requestID, UUID agentID)
394 { 352 {
395 // Don't use this, because of race conditions at agent closing time
396 //Queue<OSD> queue = TryGetQueue(agentID);
397
398 Queue<OSD> queue = GetQueue(agentID); 353 Queue<OSD> queue = GetQueue(agentID);
399 if (queue != null) 354 if (queue != null)
400 lock (queue) 355 lock (queue)
356 {
357 //m_log.WarnFormat("POLLED FOR EVENTS BY {0} in {1} -- {2}", agentID, m_scene.RegionInfo.RegionName, queue.Count);
401 return queue.Count > 0; 358 return queue.Count > 0;
359 }
402 360
403 return false; 361 //m_log.WarnFormat("POLLED FOR EVENTS BY {0} unknown agent", agentID);
362 return true;
404 } 363 }
405 364
406 /// <summary> 365 /// <summary>
@@ -414,65 +373,80 @@ namespace OpenSim.Region.ClientStack.Linden
414 OSDMap ev = (OSDMap)element; 373 OSDMap ev = (OSDMap)element;
415 m_log.DebugFormat( 374 m_log.DebugFormat(
416 "Eq OUT {0,-30} to {1,-20} {2,-20}", 375 "Eq OUT {0,-30} to {1,-20} {2,-20}",
417 ev["message"], m_scene.GetScenePresence(agentId).Name, m_scene.RegionInfo.RegionName); 376 ev["message"], m_scene.GetScenePresence(agentId).Name, m_scene.Name);
418 } 377 }
419 } 378 }
420 379
421 public Hashtable GetEvents(UUID requestID, UUID pAgentId) 380 public Hashtable GetEvents(UUID requestID, UUID pAgentId)
422 { 381 {
423 if (DebugLevel >= 2) 382 if (DebugLevel >= 2)
424 m_log.DebugFormat("POLLED FOR EQ MESSAGES BY {0} in {1}", pAgentId, m_scene.RegionInfo.RegionName); 383 m_log.WarnFormat("POLLED FOR EQ MESSAGES BY {0} in {1}", pAgentId, m_scene.Name);
425 384
426 Queue<OSD> queue = TryGetQueue(pAgentId); 385 Queue<OSD> queue = GetQueue(pAgentId);
427 OSD element; 386 if (queue == null)
428 lock (queue)
429 { 387 {
430 if (queue.Count == 0) 388 return NoEvents(requestID, pAgentId);
431 return NoEvents(requestID, pAgentId);
432 element = queue.Dequeue(); // 15s timeout
433 } 389 }
434 390
391 OSD element = null;;
392 OSDArray array = new OSDArray();
435 int thisID = 0; 393 int thisID = 0;
436 lock (m_ids) 394 bool negativeID = false;
437 thisID = m_ids[pAgentId];
438 395
439 OSDArray array = new OSDArray(); 396 lock (queue)
440 if (element == null) // didn't have an event in 15s
441 {
442 // Send it a fake event to keep the client polling! It doesn't like 502s like the proxys say!
443 array.Add(EventQueueHelper.KeepAliveEvent());
444 //m_log.DebugFormat("[EVENTQUEUE]: adding fake event for {0} in region {1}", pAgentId, m_scene.RegionInfo.RegionName);
445 }
446 else
447 { 397 {
448 if (DebugLevel > 0) 398 if (queue.Count == 0)
449 LogOutboundDebugMessage(element, pAgentId); 399 return NoEvents(requestID, pAgentId);
450 400
451 array.Add(element); 401 lock (m_ids)
402 thisID = m_ids[pAgentId];
452 403
453 lock (queue) 404 if (thisID < 0)
454 { 405 {
455 while (queue.Count > 0) 406 negativeID = true;
456 { 407 thisID = -thisID;
457 element = queue.Dequeue(); 408 }
409
410 while (queue.Count > 0)
411 {
412 element = queue.Dequeue();
413 // add elements until a marker is found
414 // so they get into a response
415 if (element == null)
416 break;
417 if (DebugLevel > 0)
418 LogOutboundDebugMessage(element, pAgentId);
419 array.Add(element);
420 thisID++;
421 }
422 }
458 423
459 if (DebugLevel > 0) 424 OSDMap events = null;
460 LogOutboundDebugMessage(element, pAgentId);
461 425
462 array.Add(element); 426 if (array.Count > 0)
463 thisID++; 427 {
464 } 428 events = new OSDMap();
465 } 429 events.Add("events", array);
430 events.Add("id", new OSDInteger(thisID));
466 } 431 }
467 432
468 OSDMap events = new OSDMap(); 433 if (negativeID && element == null)
469 events.Add("events", array); 434 {
435 Random rnd = new Random(Environment.TickCount);
436 thisID = rnd.Next(30000000);
437 if (thisID < 0)
438 thisID = -thisID;
439 }
470 440
471 events.Add("id", new OSDInteger(thisID));
472 lock (m_ids) 441 lock (m_ids)
473 { 442 {
474 m_ids[pAgentId] = thisID + 1; 443 m_ids[pAgentId] = thisID + 1;
475 } 444 }
445
446 // if there where no elements before a marker send a NoEvents
447 if (array.Count == 0)
448 return NoEvents(requestID, pAgentId);
449
476 Hashtable responsedata = new Hashtable(); 450 Hashtable responsedata = new Hashtable();
477 responsedata["int_response_code"] = 200; 451 responsedata["int_response_code"] = 200;
478 responsedata["content_type"] = "application/xml"; 452 responsedata["content_type"] = "application/xml";
@@ -495,289 +469,53 @@ namespace OpenSim.Region.ClientStack.Linden
495 responsedata["http_protocol_version"] = "HTTP/1.0"; 469 responsedata["http_protocol_version"] = "HTTP/1.0";
496 return responsedata; 470 return responsedata;
497 } 471 }
498 472
499// public Hashtable ProcessQueue(Hashtable request, UUID agentID, Caps caps)
500// {
501// // TODO: this has to be redone to not busy-wait (and block the thread),
502// // TODO: as soon as we have a non-blocking way to handle HTTP-requests.
503//
504//// if (m_log.IsDebugEnabled)
505//// {
506//// String debug = "[EVENTQUEUE]: Got request for agent {0} in region {1} from thread {2}: [ ";
507//// foreach (object key in request.Keys)
508//// {
509//// debug += key.ToString() + "=" + request[key].ToString() + " ";
510//// }
511//// m_log.DebugFormat(debug + " ]", agentID, m_scene.RegionInfo.RegionName, System.Threading.Thread.CurrentThread.Name);
512//// }
513//
514// Queue<OSD> queue = TryGetQueue(agentID);
515// OSD element;
516//
517// lock (queue)
518// element = queue.Dequeue(); // 15s timeout
519//
520// Hashtable responsedata = new Hashtable();
521//
522// int thisID = 0;
523// lock (m_ids)
524// thisID = m_ids[agentID];
525//
526// if (element == null)
527// {
528// //m_log.ErrorFormat("[EVENTQUEUE]: Nothing to process in " + m_scene.RegionInfo.RegionName);
529// if (thisID == -1) // close-request
530// {
531// m_log.ErrorFormat("[EVENTQUEUE]: 404 in " + m_scene.RegionInfo.RegionName);
532// responsedata["int_response_code"] = 404; //501; //410; //404;
533// responsedata["content_type"] = "text/plain";
534// responsedata["keepalive"] = false;
535// responsedata["str_response_string"] = "Closed EQG";
536// return responsedata;
537// }
538// responsedata["int_response_code"] = 502;
539// responsedata["content_type"] = "text/plain";
540// responsedata["keepalive"] = false;
541// responsedata["str_response_string"] = "Upstream error: ";
542// responsedata["error_status_text"] = "Upstream error:";
543// responsedata["http_protocol_version"] = "HTTP/1.0";
544// return responsedata;
545// }
546//
547// OSDArray array = new OSDArray();
548// if (element == null) // didn't have an event in 15s
549// {
550// // Send it a fake event to keep the client polling! It doesn't like 502s like the proxys say!
551// array.Add(EventQueueHelper.KeepAliveEvent());
552// //m_log.DebugFormat("[EVENTQUEUE]: adding fake event for {0} in region {1}", agentID, m_scene.RegionInfo.RegionName);
553// }
554// else
555// {
556// array.Add(element);
557//
558// if (element is OSDMap)
559// {
560// OSDMap ev = (OSDMap)element;
561// m_log.DebugFormat(
562// "[EVENT QUEUE GET MODULE]: Eq OUT {0} to {1}",
563// ev["message"], m_scene.GetScenePresence(agentID).Name);
564// }
565//
566// lock (queue)
567// {
568// while (queue.Count > 0)
569// {
570// element = queue.Dequeue();
571//
572// if (element is OSDMap)
573// {
574// OSDMap ev = (OSDMap)element;
575// m_log.DebugFormat(
576// "[EVENT QUEUE GET MODULE]: Eq OUT {0} to {1}",
577// ev["message"], m_scene.GetScenePresence(agentID).Name);
578// }
579//
580// array.Add(element);
581// thisID++;
582// }
583// }
584// }
585//
586// OSDMap events = new OSDMap();
587// events.Add("events", array);
588//
589// events.Add("id", new OSDInteger(thisID));
590// lock (m_ids)
591// {
592// m_ids[agentID] = thisID + 1;
593// }
594//
595// responsedata["int_response_code"] = 200;
596// responsedata["content_type"] = "application/xml";
597// responsedata["keepalive"] = false;
598// responsedata["str_response_string"] = OSDParser.SerializeLLSDXmlString(events);
599//
600// m_log.DebugFormat("[EVENTQUEUE]: sending response for {0} in region {1}: {2}", agentID, m_scene.RegionInfo.RegionName, responsedata["str_response_string"]);
601//
602// return responsedata;
603// }
604
605// public Hashtable EventQueuePath2(Hashtable request)
606// {
607// string capuuid = (string)request["uri"]; //path.Replace("/CAPS/EQG/","");
608// // pull off the last "/" in the path.
609// Hashtable responsedata = new Hashtable();
610// capuuid = capuuid.Substring(0, capuuid.Length - 1);
611// capuuid = capuuid.Replace("/CAPS/EQG/", "");
612// UUID AvatarID = UUID.Zero;
613// UUID capUUID = UUID.Zero;
614//
615// // parse the path and search for the avatar with it registered
616// if (UUID.TryParse(capuuid, out capUUID))
617// {
618// lock (m_QueueUUIDAvatarMapping)
619// {
620// if (m_QueueUUIDAvatarMapping.ContainsKey(capUUID))
621// {
622// AvatarID = m_QueueUUIDAvatarMapping[capUUID];
623// }
624// }
625//
626// if (AvatarID != UUID.Zero)
627// {
628// return ProcessQueue(request, AvatarID, m_scene.CapsModule.GetCapsForUser(AvatarID));
629// }
630// else
631// {
632// responsedata["int_response_code"] = 404;
633// responsedata["content_type"] = "text/plain";
634// responsedata["keepalive"] = false;
635// responsedata["str_response_string"] = "Not Found";
636// responsedata["error_status_text"] = "Not Found";
637// responsedata["http_protocol_version"] = "HTTP/1.0";
638// return responsedata;
639// // return 404
640// }
641// }
642// else
643// {
644// responsedata["int_response_code"] = 404;
645// responsedata["content_type"] = "text/plain";
646// responsedata["keepalive"] = false;
647// responsedata["str_response_string"] = "Not Found";
648// responsedata["error_status_text"] = "Not Found";
649// responsedata["http_protocol_version"] = "HTTP/1.0";
650// return responsedata;
651// // return 404
652// }
653// }
654
655 public OSD EventQueueFallBack(string path, OSD request, string endpoint)
656 {
657 // This is a fallback element to keep the client from loosing EventQueueGet
658 // Why does CAPS fail sometimes!?
659 m_log.Warn("[EVENTQUEUE]: In the Fallback handler! We lost the Queue in the rest handler!");
660 string capuuid = path.Replace("/CAPS/EQG/","");
661 capuuid = capuuid.Substring(0, capuuid.Length - 1);
662
663// UUID AvatarID = UUID.Zero;
664 UUID capUUID = UUID.Zero;
665 if (UUID.TryParse(capuuid, out capUUID))
666 {
667/* Don't remove this yet code cleaners!
668 * Still testing this!
669 *
670 lock (m_QueueUUIDAvatarMapping)
671 {
672 if (m_QueueUUIDAvatarMapping.ContainsKey(capUUID))
673 {
674 AvatarID = m_QueueUUIDAvatarMapping[capUUID];
675 }
676 }
677
678
679 if (AvatarID != UUID.Zero)
680 {
681 // Repair the CAP!
682 //OpenSim.Framework.Capabilities.Caps caps = m_scene.GetCapsHandlerForUser(AvatarID);
683 //string capsBase = "/CAPS/EQG/";
684 //caps.RegisterHandler("EventQueueGet",
685 //new RestHTTPHandler("POST", capsBase + capUUID.ToString() + "/",
686 //delegate(Hashtable m_dhttpMethod)
687 //{
688 // return ProcessQueue(m_dhttpMethod, AvatarID, caps);
689 //}));
690 // start new ID sequence.
691 Random rnd = new Random(System.Environment.TickCount);
692 lock (m_ids)
693 {
694 if (!m_ids.ContainsKey(AvatarID))
695 m_ids.Add(AvatarID, rnd.Next(30000000));
696 }
697
698
699 int thisID = 0;
700 lock (m_ids)
701 thisID = m_ids[AvatarID];
702
703 BlockingLLSDQueue queue = GetQueue(AvatarID);
704 OSDArray array = new OSDArray();
705 LLSD element = queue.Dequeue(15000); // 15s timeout
706 if (element == null)
707 {
708
709 array.Add(EventQueueHelper.KeepAliveEvent());
710 }
711 else
712 {
713 array.Add(element);
714 while (queue.Count() > 0)
715 {
716 array.Add(queue.Dequeue(1));
717 thisID++;
718 }
719 }
720 OSDMap events = new OSDMap();
721 events.Add("events", array);
722
723 events.Add("id", new LLSDInteger(thisID));
724
725 lock (m_ids)
726 {
727 m_ids[AvatarID] = thisID + 1;
728 }
729
730 return events;
731 }
732 else
733 {
734 return new LLSD();
735 }
736*
737*/
738 }
739 else
740 {
741 //return new LLSD();
742 }
743
744 return new OSDString("shutdown404!");
745 }
746
747 public void DisableSimulator(ulong handle, UUID avatarID) 473 public void DisableSimulator(ulong handle, UUID avatarID)
748 { 474 {
749 OSD item = EventQueueHelper.DisableSimulator(handle); 475 OSD item = EventQueueHelper.DisableSimulator(handle);
750 Enqueue(item, avatarID); 476 Enqueue(item, avatarID);
751 } 477 }
752 478
753 public virtual void EnableSimulator(ulong handle, IPEndPoint endPoint, UUID avatarID) 479 public virtual void EnableSimulator(ulong handle, IPEndPoint endPoint, UUID avatarID, int regionSizeX, int regionSizeY)
754 { 480 {
755 OSD item = EventQueueHelper.EnableSimulator(handle, endPoint); 481 m_log.DebugFormat("{0} EnableSimulator. handle={1}, avatarID={2}, regionSize={3},{4}>",
482 "[EVENT QUEUE GET MODULE]", handle, avatarID, regionSizeX, regionSizeY);
483
484 OSD item = EventQueueHelper.EnableSimulator(handle, endPoint, regionSizeX, regionSizeY);
756 Enqueue(item, avatarID); 485 Enqueue(item, avatarID);
757 } 486 }
758 487
759 public virtual void EstablishAgentCommunication(UUID avatarID, IPEndPoint endPoint, string capsPath) 488 public virtual void EstablishAgentCommunication(UUID avatarID, IPEndPoint endPoint, string capsPath,
489 ulong regionHandle, int regionSizeX, int regionSizeY)
760 { 490 {
761 OSD item = EventQueueHelper.EstablishAgentCommunication(avatarID, endPoint.ToString(), capsPath); 491 m_log.DebugFormat("{0} EstablishAgentCommunication. handle={1}, avatarID={2}, regionSize={3},{4}>",
492 "[EVENT QUEUE GET MODULE]", regionHandle, avatarID, regionSizeX, regionSizeY);
493 OSD item = EventQueueHelper.EstablishAgentCommunication(avatarID, endPoint.ToString(), capsPath, regionHandle, regionSizeX, regionSizeY);
762 Enqueue(item, avatarID); 494 Enqueue(item, avatarID);
763 } 495 }
764 496
765 public virtual void TeleportFinishEvent(ulong regionHandle, byte simAccess, 497 public virtual void TeleportFinishEvent(ulong regionHandle, byte simAccess,
766 IPEndPoint regionExternalEndPoint, 498 IPEndPoint regionExternalEndPoint,
767 uint locationID, uint flags, string capsURL, 499 uint locationID, uint flags, string capsURL,
768 UUID avatarID) 500 UUID avatarID, int regionSizeX, int regionSizeY)
769 { 501 {
502 m_log.DebugFormat("{0} TeleportFinishEvent. handle={1}, avatarID={2}, regionSize={3},{4}>",
503 "[EVENT QUEUE GET MODULE]", regionHandle, avatarID, regionSizeX, regionSizeY);
504
770 OSD item = EventQueueHelper.TeleportFinishEvent(regionHandle, simAccess, regionExternalEndPoint, 505 OSD item = EventQueueHelper.TeleportFinishEvent(regionHandle, simAccess, regionExternalEndPoint,
771 locationID, flags, capsURL, avatarID); 506 locationID, flags, capsURL, avatarID, regionSizeX, regionSizeY);
772 Enqueue(item, avatarID); 507 Enqueue(item, avatarID);
773 } 508 }
774 509
775 public virtual void CrossRegion(ulong handle, Vector3 pos, Vector3 lookAt, 510 public virtual void CrossRegion(ulong handle, Vector3 pos, Vector3 lookAt,
776 IPEndPoint newRegionExternalEndPoint, 511 IPEndPoint newRegionExternalEndPoint,
777 string capsURL, UUID avatarID, UUID sessionID) 512 string capsURL, UUID avatarID, UUID sessionID, int regionSizeX, int regionSizeY)
778 { 513 {
514 m_log.DebugFormat("{0} CrossRegion. handle={1}, avatarID={2}, regionSize={3},{4}>",
515 "[EVENT QUEUE GET MODULE]", handle, avatarID, regionSizeX, regionSizeY);
516
779 OSD item = EventQueueHelper.CrossRegion(handle, pos, lookAt, newRegionExternalEndPoint, 517 OSD item = EventQueueHelper.CrossRegion(handle, pos, lookAt, newRegionExternalEndPoint,
780 capsURL, avatarID, sessionID); 518 capsURL, avatarID, sessionID, regionSizeX, regionSizeY);
781 Enqueue(item, avatarID); 519 Enqueue(item, avatarID);
782 } 520 }
783 521
@@ -794,12 +532,12 @@ namespace OpenSim.Region.ClientStack.Linden
794 532
795 } 533 }
796 534
797 public void ChatterBoxSessionAgentListUpdates(UUID sessionID, UUID fromAgent, UUID toAgent, bool canVoiceChat, 535 public void ChatterBoxSessionAgentListUpdates(UUID sessionID, UUID fromAgent, UUID anotherAgent, bool canVoiceChat,
798 bool isModerator, bool textMute) 536 bool isModerator, bool textMute)
799 { 537 {
800 OSD item = EventQueueHelper.ChatterBoxSessionAgentListUpdates(sessionID, fromAgent, canVoiceChat, 538 OSD item = EventQueueHelper.ChatterBoxSessionAgentListUpdates(sessionID, fromAgent, canVoiceChat,
801 isModerator, textMute); 539 isModerator, textMute);
802 Enqueue(item, toAgent); 540 Enqueue(item, fromAgent);
803 //m_log.InfoFormat("########### eq ChatterBoxSessionAgentListUpdates #############\n{0}", item); 541 //m_log.InfoFormat("########### eq ChatterBoxSessionAgentListUpdates #############\n{0}", item);
804 } 542 }
805 543