aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/Scripting
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/CoreModules/Scripting')
-rw-r--r--OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs225
-rw-r--r--OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs439
-rw-r--r--OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs81
5 files changed, 430 insertions, 319 deletions
diff --git a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs
index 9dfeb96..87f4798 100644
--- a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs
+++ b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs
@@ -28,15 +28,12 @@
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.IO; 30using System.IO;
31using System.Linq;
32using System.Net; 31using System.Net;
33using System.Net.Mail; 32using System.Net.Mail;
34using System.Net.Security; 33using System.Net.Security;
35using System.Reflection;
36using System.Text; 34using System.Text;
37using System.Threading; 35using System.Threading;
38using System.Security.Cryptography.X509Certificates; 36using System.Security.Cryptography.X509Certificates;
39using log4net;
40using Nini.Config; 37using Nini.Config;
41using OpenMetaverse; 38using OpenMetaverse;
42using OpenSim.Framework; 39using OpenSim.Framework;
@@ -45,6 +42,7 @@ using OpenSim.Framework.Servers.HttpServer;
45using OpenSim.Region.Framework.Interfaces; 42using OpenSim.Region.Framework.Interfaces;
46using OpenSim.Region.Framework.Scenes; 43using OpenSim.Region.Framework.Scenes;
47using Mono.Addins; 44using Mono.Addins;
45using Amib.Threading;
48 46
49/***************************************************** 47/*****************************************************
50 * 48 *
@@ -108,6 +106,7 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
108 private Dictionary<UUID, HttpRequestClass> m_pendingRequests; 106 private Dictionary<UUID, HttpRequestClass> m_pendingRequests;
109 private Scene m_scene; 107 private Scene m_scene;
110 // private Queue<HttpRequestClass> rpcQueue = new Queue<HttpRequestClass>(); 108 // private Queue<HttpRequestClass> rpcQueue = new Queue<HttpRequestClass>();
109 public static SmartThreadPool ThreadPool = null;
111 110
112 public HttpRequestModule() 111 public HttpRequestModule()
113 { 112 {
@@ -290,29 +289,18 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
290 return true; 289 return true;
291 } 290 }
292 291
293 public void StopHttpRequestsForScript(UUID id) 292 public void StopHttpRequest(uint m_localID, UUID m_itemID)
294 { 293 {
295 if (m_pendingRequests != null) 294 if (m_pendingRequests != null)
296 { 295 {
297 List<UUID> keysToRemove = null;
298
299 lock (HttpListLock) 296 lock (HttpListLock)
300 { 297 {
301 foreach (HttpRequestClass req in m_pendingRequests.Values) 298 HttpRequestClass tmpReq;
299 if (m_pendingRequests.TryGetValue(m_itemID, out tmpReq))
302 { 300 {
303 if (req.ItemID == id) 301 tmpReq.Stop();
304 { 302 m_pendingRequests.Remove(m_itemID);
305 req.Stop();
306
307 if (keysToRemove == null)
308 keysToRemove = new List<UUID>();
309
310 keysToRemove.Add(req.ReqID);
311 }
312 } 303 }
313
314 if (keysToRemove != null)
315 keysToRemove.ForEach(keyToRemove => m_pendingRequests.Remove(keyToRemove));
316 } 304 }
317 } 305 }
318 } 306 }
@@ -330,13 +318,19 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
330 { 318 {
331 lock (HttpListLock) 319 lock (HttpListLock)
332 { 320 {
333 foreach (HttpRequestClass req in m_pendingRequests.Values) 321 foreach (UUID luid in m_pendingRequests.Keys)
334 { 322 {
335 if (req.Finished) 323 HttpRequestClass tmpReq;
336 return req; 324
325 if (m_pendingRequests.TryGetValue(luid, out tmpReq))
326 {
327 if (tmpReq.Finished)
328 {
329 return tmpReq;
330 }
331 }
337 } 332 }
338 } 333 }
339
340 return null; 334 return null;
341 } 335 }
342 336
@@ -363,9 +357,32 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
363 m_proxyurl = config.Configs["Startup"].GetString("HttpProxy"); 357 m_proxyurl = config.Configs["Startup"].GetString("HttpProxy");
364 m_proxyexcepts = config.Configs["Startup"].GetString("HttpProxyExceptions"); 358 m_proxyexcepts = config.Configs["Startup"].GetString("HttpProxyExceptions");
365 359
360
366 m_outboundUrlFilter = new OutboundUrlFilter("Script HTTP request module", config); 361 m_outboundUrlFilter = new OutboundUrlFilter("Script HTTP request module", config);
362 int maxThreads = 15;
363
364 IConfig httpConfig = config.Configs["HttpRequestModule"];
365 if (httpConfig != null)
366 {
367 maxThreads = httpConfig.GetInt("MaxPoolThreads", maxThreads);
368 }
367 369
368 m_pendingRequests = new Dictionary<UUID, HttpRequestClass>(); 370 m_pendingRequests = new Dictionary<UUID, HttpRequestClass>();
371
372 // First instance sets this up for all sims
373 if (ThreadPool == null)
374 {
375 STPStartInfo startInfo = new STPStartInfo();
376 startInfo.IdleTimeout = 20000;
377 startInfo.MaxWorkerThreads = maxThreads;
378 startInfo.MinWorkerThreads = 1;
379 startInfo.ThreadPriority = ThreadPriority.BelowNormal;
380 startInfo.StartSuspended = true;
381 startInfo.ThreadPoolName = "ScriptsHttpReq";
382
383 ThreadPool = new SmartThreadPool(startInfo);
384 ThreadPool.Start();
385 }
369 } 386 }
370 387
371 public void AddRegion(Scene scene) 388 public void AddRegion(Scene scene)
@@ -409,8 +426,6 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
409 426
410 public class HttpRequestClass : IServiceRequest 427 public class HttpRequestClass : IServiceRequest
411 { 428 {
412// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
413
414 // Constants for parameters 429 // Constants for parameters
415 // public const int HTTP_BODY_MAXLENGTH = 2; 430 // public const int HTTP_BODY_MAXLENGTH = 2;
416 // public const int HTTP_METHOD = 0; 431 // public const int HTTP_METHOD = 0;
@@ -437,6 +452,8 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
437 public string HttpMIMEType = "text/plain;charset=utf-8"; 452 public string HttpMIMEType = "text/plain;charset=utf-8";
438 public int HttpTimeout; 453 public int HttpTimeout;
439 public bool HttpVerifyCert = true; 454 public bool HttpVerifyCert = true;
455 public IWorkItemResult WorkItem = null;
456
440 //public bool HttpVerboseThrottle = true; // not implemented 457 //public bool HttpVerboseThrottle = true; // not implemented
441 public List<string> HttpCustomHeaders = null; 458 public List<string> HttpCustomHeaders = null;
442 public bool HttpPragmaNoCache = true; 459 public bool HttpPragmaNoCache = true;
@@ -484,15 +501,40 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
484 501
485 public void Process() 502 public void Process()
486 { 503 {
504 _finished = false;
505
506 lock (HttpRequestModule.ThreadPool)
507 WorkItem = HttpRequestModule.ThreadPool.QueueWorkItem(new WorkItemCallback(StpSendWrapper), null);
508 }
509
510 private object StpSendWrapper(object o)
511 {
487 SendRequest(); 512 SendRequest();
513 return null;
488 } 514 }
489 515
516 /*
517 * TODO: More work on the response codes. Right now
518 * returning 200 for success or 499 for exception
519 */
520
490 public void SendRequest() 521 public void SendRequest()
491 { 522 {
523 HttpWebResponse response = null;
524 Stream resStream = null;
525 StringBuilder sb = new StringBuilder();
526 byte[] buf = new byte[8192];
527 string tempString = null;
528 int count = 0;
529
492 try 530 try
493 { 531 {
494 Request = (HttpWebRequest)WebRequest.Create(Url); 532 Request = (HttpWebRequest)WebRequest.Create(Url);
495 Request.AllowAutoRedirect = false; 533 Request.AllowAutoRedirect = false;
534
535 //This works around some buggy HTTP Servers like Lighttpd
536 Request.ServicePoint.Expect100Continue = false;
537
496 Request.Method = HttpMethod; 538 Request.Method = HttpMethod;
497 Request.ContentType = HttpMIMEType; 539 Request.ContentType = HttpMIMEType;
498 540
@@ -500,7 +542,6 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
500 { 542 {
501 // We could hijack Connection Group Name to identify 543 // We could hijack Connection Group Name to identify
502 // a desired security exception. But at the moment we'll use a dummy header instead. 544 // a desired security exception. But at the moment we'll use a dummy header instead.
503// Request.ConnectionGroupName = "NoVerify";
504 Request.Headers.Add("NoVerifyCert", "true"); 545 Request.Headers.Add("NoVerifyCert", "true");
505 } 546 }
506// else 547// else
@@ -533,14 +574,11 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
533 } 574 }
534 } 575 }
535 576
536 if (ResponseHeaders != null) 577 foreach (KeyValuePair<string, string> entry in ResponseHeaders)
537 { 578 if (entry.Key.ToLower().Equals("user-agent"))
538 foreach (KeyValuePair<string, string> entry in ResponseHeaders) 579 Request.UserAgent = entry.Value;
539 if (entry.Key.ToLower().Equals("user-agent") && Request is HttpWebRequest) 580 else
540 ((HttpWebRequest)Request).UserAgent = entry.Value; 581 Request.Headers[entry.Key] = entry.Value;
541 else
542 Request.Headers[entry.Key] = entry.Value;
543 }
544 582
545 // Encode outbound data 583 // Encode outbound data
546 if (!string.IsNullOrEmpty(OutboundBody)) 584 if (!string.IsNullOrEmpty(OutboundBody))
@@ -552,12 +590,11 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
552 bstream.Write(data, 0, data.Length); 590 bstream.Write(data, 0, data.Length);
553 } 591 }
554 592
593 Request.Timeout = HttpTimeout;
555 try 594 try
556 { 595 {
557 IAsyncResult result = (IAsyncResult)Request.BeginGetResponse(ResponseCallback, null); 596 // execute the request
558 597 response = (HttpWebResponse) Request.GetResponse();
559 ThreadPool.RegisterWaitForSingleObject(
560 result.AsyncWaitHandle, new WaitOrTimerCallback(TimeoutCallback), null, HttpTimeout, true);
561 } 598 }
562 catch (WebException e) 599 catch (WebException e)
563 { 600 {
@@ -565,63 +602,72 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
565 { 602 {
566 throw; 603 throw;
567 } 604 }
605 response = (HttpWebResponse)e.Response;
606 }
568 607
569 HttpWebResponse response = (HttpWebResponse)e.Response; 608 Status = (int)response.StatusCode;
570 609
571 Status = (int)response.StatusCode; 610 resStream = response.GetResponseStream();
572 ResponseBody = response.StatusDescription;
573 _finished = true;
574 }
575 }
576 catch (Exception e)
577 {
578// m_log.Debug(
579// string.Format("[SCRIPTS HTTP REQUESTS]: Exception on request to {0} for {1} ", Url, ItemID), e);
580 611
581 Status = (int)OSHttpStatusCode.ClientErrorJoker; 612 do
582 ResponseBody = e.Message; 613 {
583 _finished = true; 614 // fill the buffer with data
584 } 615 count = resStream.Read(buf, 0, buf.Length);
585 }
586 616
587 private void ResponseCallback(IAsyncResult ar) 617 // make sure we read some data
588 { 618 if (count != 0)
589 HttpWebResponse response = null; 619 {
620 // translate from bytes to ASCII text
621 tempString = Util.UTF8.GetString(buf, 0, count);
590 622
591 try 623 // continue building the string
624 sb.Append(tempString);
625 if (sb.Length > 2048)
626 break;
627 }
628 } while (count > 0); // any more data to read?
629
630 ResponseBody = sb.ToString().Replace("\r", "");
631 }
632 catch (WebException e)
592 { 633 {
593 try 634 if (e.Status == WebExceptionStatus.ProtocolError)
594 { 635 {
595 response = (HttpWebResponse)Request.EndGetResponse(ar); 636 HttpWebResponse webRsp = (HttpWebResponse)((WebException)e).Response;
596 } 637 Status = (int)webRsp.StatusCode;
597 catch (WebException e) 638 try
598 {
599 if (e.Status != WebExceptionStatus.ProtocolError)
600 { 639 {
601 throw; 640 using (Stream responseStream = webRsp.GetResponseStream())
641 {
642 using (StreamReader reader = new StreamReader(responseStream))
643 ResponseBody = reader.ReadToEnd();
644 }
645 }
646 catch
647 {
648 ResponseBody = webRsp.StatusDescription;
602 } 649 }
603 650 }
604 response = (HttpWebResponse)e.Response; 651 else
652 {
653 Status = (int)OSHttpStatusCode.ClientErrorJoker;
654 ResponseBody = e.Message;
605 } 655 }
606 656
607 Status = (int)response.StatusCode; 657 if (ResponseBody == null)
658 ResponseBody = String.Empty;
608 659
609 using (Stream stream = response.GetResponseStream()) 660 _finished = true;
610 { 661 return;
611 StreamReader reader = new StreamReader(stream, Encoding.UTF8);
612 ResponseBody = reader.ReadToEnd();
613 }
614 } 662 }
615 catch (Exception e) 663 catch (Exception e)
616 { 664 {
617 Status = (int)OSHttpStatusCode.ClientErrorJoker; 665 // Don't crash on anything else
618 ResponseBody = e.Message;
619
620// m_log.Debug(
621// string.Format("[SCRIPTS HTTP REQUESTS]: Exception on response to {0} for {1} ", Url, ItemID), e);
622 } 666 }
623 finally 667 finally
624 { 668 {
669 if (resStream != null)
670 resStream.Close();
625 if (response != null) 671 if (response != null)
626 response.Close(); 672 response.Close();
627 673
@@ -672,20 +718,25 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
672 _finished = true; 718 _finished = true;
673 } 719 }
674 } 720 }
675 }
676 721
677 private void TimeoutCallback(object state, bool timedOut) 722 if (ResponseBody == null)
678 { 723 ResponseBody = String.Empty;
679 if (timedOut) 724
680 Request.Abort(); 725 _finished = true;
681 } 726 }
682 727
683 public void Stop() 728 public void Stop()
684 { 729 {
685// m_log.DebugFormat("[SCRIPTS HTTP REQUESTS]: Stopping request to {0} for {1} ", Url, ItemID); 730 try
686 731 {
687 if (Request != null) 732 if (!WorkItem.Cancel())
688 Request.Abort(); 733 {
734 WorkItem.Cancel(true);
735 }
736 }
737 catch (Exception)
738 {
739 }
689 } 740 }
690 } 741 }
691} \ No newline at end of file 742}
diff --git a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs
index 99a3122..a21931c 100644
--- a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs
@@ -42,40 +42,16 @@ using OpenSim.Region.Framework.Scenes;
42 42
43namespace OpenSim.Region.CoreModules.Scripting.LSLHttp 43namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
44{ 44{
45 /// <summary>
46 /// Data describing an external URL set up by a script.
47 /// </summary>
48 public class UrlData 45 public class UrlData
49 { 46 {
50 /// <summary>
51 /// Scene object part hosting the script
52 /// </summary>
53 public UUID hostID; 47 public UUID hostID;
54
55 /// <summary>
56 /// The item ID of the script that requested the URL.
57 /// </summary>
58 public UUID itemID; 48 public UUID itemID;
59
60 /// <summary>
61 /// The script engine that runs the script.
62 /// </summary>
63 public IScriptModule engine; 49 public IScriptModule engine;
64
65 /// <summary>
66 /// The generated URL.
67 /// </summary>
68 public string url; 50 public string url;
69
70 /// <summary>
71 /// The random UUID component of the generated URL.
72 /// </summary>
73 public UUID urlcode; 51 public UUID urlcode;
74
75 /// <summary>
76 /// The external requests currently being processed or awaiting retrieval for this URL.
77 /// </summary>
78 public Dictionary<UUID, RequestData> requests; 52 public Dictionary<UUID, RequestData> requests;
53 public bool isSsl;
54 public Scene scene;
79 } 55 }
80 56
81 public class RequestData 57 public class RequestData
@@ -89,7 +65,11 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
89 //public ManualResetEvent ev; 65 //public ManualResetEvent ev;
90 public bool requestDone; 66 public bool requestDone;
91 public int startTime; 67 public int startTime;
68 public bool responseSent;
92 public string uri; 69 public string uri;
70 public bool allowResponseType = false;
71 public UUID hostID;
72 public Scene scene;
93 } 73 }
94 74
95 /// <summary> 75 /// <summary>
@@ -102,20 +82,11 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
102 LogManager.GetLogger( 82 LogManager.GetLogger(
103 MethodBase.GetCurrentMethod().DeclaringType); 83 MethodBase.GetCurrentMethod().DeclaringType);
104 84
105 /// <summary> 85 private Dictionary<UUID, UrlData> m_RequestMap =
106 /// Indexs the URL request metadata (which script requested it, outstanding requests, etc.) by the request ID 86 new Dictionary<UUID, UrlData>();
107 /// randomly generated when a request is received for this URL.
108 /// </summary>
109 /// <remarks>
110 /// Manipulation or retrieval from this dictionary must be locked on m_UrlMap to preserve consistency with
111 /// m_UrlMap
112 /// </remarks>
113 private Dictionary<UUID, UrlData> m_RequestMap = new Dictionary<UUID, UrlData>();
114 87
115 /// <summary> 88 private Dictionary<string, UrlData> m_UrlMap =
116 /// Indexs the URL request metadata (which script requested it, outstanding requests, etc.) by the full URL 89 new Dictionary<string, UrlData>();
117 /// </summary>
118 private Dictionary<string, UrlData> m_UrlMap = new Dictionary<string, UrlData>();
119 90
120 private uint m_HttpsPort = 0; 91 private uint m_HttpsPort = 0;
121 private IHttpServer m_HttpServer = null; 92 private IHttpServer m_HttpServer = null;
@@ -126,7 +97,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
126 /// <summary> 97 /// <summary>
127 /// The default maximum number of urls 98 /// The default maximum number of urls
128 /// </summary> 99 /// </summary>
129 public const int DefaultTotalUrls = 100; 100 public const int DefaultTotalUrls = 15000;
130 101
131 /// <summary> 102 /// <summary>
132 /// Maximum number of external urls that can be set up by this module. 103 /// Maximum number of external urls that can be set up by this module.
@@ -204,6 +175,17 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
204 175
205 public void RemoveRegion(Scene scene) 176 public void RemoveRegion(Scene scene)
206 { 177 {
178 // Drop references to that scene
179 foreach (KeyValuePair<string, UrlData> kvp in m_UrlMap)
180 {
181 if (kvp.Value.scene == scene)
182 kvp.Value.scene = null;
183 }
184 foreach (KeyValuePair<UUID, UrlData> kvp in m_RequestMap)
185 {
186 if (kvp.Value.scene == scene)
187 kvp.Value.scene = null;
188 }
207 } 189 }
208 190
209 public void Close() 191 public void Close()
@@ -229,8 +211,10 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
229 urlData.engine = engine; 211 urlData.engine = engine;
230 urlData.url = url; 212 urlData.url = url;
231 urlData.urlcode = urlcode; 213 urlData.urlcode = urlcode;
214 urlData.isSsl = false;
232 urlData.requests = new Dictionary<UUID, RequestData>(); 215 urlData.requests = new Dictionary<UUID, RequestData>();
233 216 urlData.scene = host.ParentGroup.Scene;
217
234 m_UrlMap[url] = urlData; 218 m_UrlMap[url] = urlData;
235 219
236 string uri = "/lslhttp/" + urlcode.ToString() + "/"; 220 string uri = "/lslhttp/" + urlcode.ToString() + "/";
@@ -240,9 +224,9 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
240 args.Type = PollServiceEventArgs.EventType.LslHttp; 224 args.Type = PollServiceEventArgs.EventType.LslHttp;
241 m_HttpServer.AddPollServiceHTTPHandler(uri, args); 225 m_HttpServer.AddPollServiceHTTPHandler(uri, args);
242 226
243 m_log.DebugFormat( 227// m_log.DebugFormat(
244 "[URL MODULE]: Set up incoming request url {0} for {1} in {2} {3}", 228// "[URL MODULE]: Set up incoming request url {0} for {1} in {2} {3}",
245 uri, itemID, host.Name, host.LocalId); 229// uri, itemID, host.Name, host.LocalId);
246 230
247 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_GRANTED", url }); 231 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_GRANTED", url });
248 } 232 }
@@ -275,8 +259,10 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
275 urlData.engine = engine; 259 urlData.engine = engine;
276 urlData.url = url; 260 urlData.url = url;
277 urlData.urlcode = urlcode; 261 urlData.urlcode = urlcode;
262 urlData.isSsl = true;
278 urlData.requests = new Dictionary<UUID, RequestData>(); 263 urlData.requests = new Dictionary<UUID, RequestData>();
279 264
265
280 m_UrlMap[url] = urlData; 266 m_UrlMap[url] = urlData;
281 267
282 string uri = "/lslhttps/" + urlcode.ToString() + "/"; 268 string uri = "/lslhttps/" + urlcode.ToString() + "/";
@@ -286,9 +272,9 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
286 args.Type = PollServiceEventArgs.EventType.LslHttp; 272 args.Type = PollServiceEventArgs.EventType.LslHttp;
287 m_HttpsServer.AddPollServiceHTTPHandler(uri, args); 273 m_HttpsServer.AddPollServiceHTTPHandler(uri, args);
288 274
289 m_log.DebugFormat( 275// m_log.DebugFormat(
290 "[URL MODULE]: Set up incoming secure request url {0} for {1} in {2} {3}", 276// "[URL MODULE]: Set up incoming secure request url {0} for {1} in {2} {3}",
291 uri, itemID, host.Name, host.LocalId); 277// uri, itemID, host.Name, host.LocalId);
292 278
293 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_GRANTED", url }); 279 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_GRANTED", url });
294 } 280 }
@@ -307,12 +293,15 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
307 return; 293 return;
308 } 294 }
309 295
310 foreach (UUID req in data.requests.Keys) 296 lock (m_RequestMap)
311 m_RequestMap.Remove(req); 297 {
312 298 foreach (UUID req in data.requests.Keys)
313 m_log.DebugFormat( 299 m_RequestMap.Remove(req);
314 "[URL MODULE]: Releasing url {0} for {1} in {2}", 300 }
315 url, data.itemID, data.hostID); 301
302// m_log.DebugFormat(
303// "[URL MODULE]: Releasing url {0} for {1} in {2}",
304// url, data.itemID, data.hostID);
316 305
317 RemoveUrl(data); 306 RemoveUrl(data);
318 m_UrlMap.Remove(url); 307 m_UrlMap.Remove(url);
@@ -337,29 +326,39 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
337 326
338 public void HttpResponse(UUID request, int status, string body) 327 public void HttpResponse(UUID request, int status, string body)
339 { 328 {
340 lock (m_UrlMap) 329 lock (m_RequestMap)
341 { 330 {
342 if (m_RequestMap.ContainsKey(request)) 331 if (m_RequestMap.ContainsKey(request))
343 { 332 {
344 UrlData urlData = m_RequestMap[request]; 333 UrlData urlData = m_RequestMap[request];
345 string responseBody = body; 334 if (!urlData.requests[request].responseSent)
346 if (urlData.requests[request].responseType.Equals("text/plain"))
347 { 335 {
348 string value; 336 string responseBody = body;
349 if (urlData.requests[request].headers.TryGetValue("user-agent", out value)) 337
338 // If we have no OpenID from built-in browser, disable this
339 if (!urlData.requests[request].allowResponseType)
340 urlData.requests[request].responseType = "text/plain";
341
342 if (urlData.requests[request].responseType.Equals("text/plain"))
350 { 343 {
351 if (value != null && value.IndexOf("MSIE") >= 0) 344 string value;
345 if (urlData.requests[request].headers.TryGetValue("user-agent", out value))
352 { 346 {
353 // wrap the html escaped response if the target client is IE 347 if (value != null && value.IndexOf("MSIE") >= 0)
354 // It ignores "text/plain" if the body is html 348 {
355 responseBody = "<html>" + System.Web.HttpUtility.HtmlEncode(body) + "</html>"; 349 // wrap the html escaped response if the target client is IE
350 // It ignores "text/plain" if the body is html
351 responseBody = "<html>" + System.Web.HttpUtility.HtmlEncode(body) + "</html>";
352 }
356 } 353 }
357 } 354 }
355
356 urlData.requests[request].responseCode = status;
357 urlData.requests[request].responseBody = body;
358 //urlData.requests[request].ev.Set();
359 urlData.requests[request].requestDone = true;
360 urlData.requests[request].responseSent = true;
358 } 361 }
359 urlData.requests[request].responseCode = status;
360 urlData.requests[request].responseBody = responseBody;
361 //urlData.requests[request].ev.Set();
362 urlData.requests[request].requestDone =true;
363 } 362 }
364 else 363 else
365 { 364 {
@@ -370,7 +369,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
370 369
371 public string GetHttpHeader(UUID requestId, string header) 370 public string GetHttpHeader(UUID requestId, string header)
372 { 371 {
373 lock (m_UrlMap) 372 lock (m_RequestMap)
374 { 373 {
375 if (m_RequestMap.ContainsKey(requestId)) 374 if (m_RequestMap.ContainsKey(requestId))
376 { 375 {
@@ -384,7 +383,6 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
384 m_log.Warn("[HttpRequestHandler] There was no http-in request with id " + requestId); 383 m_log.Warn("[HttpRequestHandler] There was no http-in request with id " + requestId);
385 } 384 }
386 } 385 }
387
388 return String.Empty; 386 return String.Empty;
389 } 387 }
390 388
@@ -408,8 +406,11 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
408 { 406 {
409 RemoveUrl(url.Value); 407 RemoveUrl(url.Value);
410 removeURLs.Add(url.Key); 408 removeURLs.Add(url.Key);
411 foreach (UUID req in url.Value.requests.Keys) 409 lock (m_RequestMap)
412 m_RequestMap.Remove(req); 410 {
411 foreach (UUID req in url.Value.requests.Keys)
412 m_RequestMap.Remove(req);
413 }
413 } 414 }
414 } 415 }
415 416
@@ -430,9 +431,11 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
430 { 431 {
431 RemoveUrl(url.Value); 432 RemoveUrl(url.Value);
432 removeURLs.Add(url.Key); 433 removeURLs.Add(url.Key);
433 434 lock (m_RequestMap)
434 foreach (UUID req in url.Value.requests.Keys) 435 {
435 m_RequestMap.Remove(req); 436 foreach (UUID req in url.Value.requests.Keys)
437 m_RequestMap.Remove(req);
438 }
436 } 439 }
437 } 440 }
438 441
@@ -441,123 +444,128 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
441 } 444 }
442 } 445 }
443 446
447
444 private void RemoveUrl(UrlData data) 448 private void RemoveUrl(UrlData data)
445 { 449 {
446 m_HttpServer.RemoveHTTPHandler("", "/lslhttp/" + data.urlcode.ToString() + "/"); 450 if (data.isSsl)
451 m_HttpsServer.RemoveHTTPHandler("", "/lslhttps/"+data.urlcode.ToString()+"/");
452 else
453 m_HttpServer.RemoveHTTPHandler("", "/lslhttp/"+data.urlcode.ToString()+"/");
447 } 454 }
448 455
449 private Hashtable NoEvents(UUID requestID, UUID sessionID) 456 private Hashtable NoEvents(UUID requestID, UUID sessionID)
450 { 457 {
451 Hashtable response = new Hashtable(); 458 Hashtable response = new Hashtable();
452 UrlData urlData; 459 UrlData url;
453 460 int startTime = 0;
454 lock (m_UrlMap) 461 lock (m_RequestMap)
455 { 462 {
456 // We need to return a 404 here in case the request URL was removed at exactly the same time that a
457 // request was made. In this case, the request thread can outrace llRemoveURL() and still be polling
458 // for the request ID.
459 if (!m_RequestMap.ContainsKey(requestID)) 463 if (!m_RequestMap.ContainsKey(requestID))
460 {
461 response["int_response_code"] = 404;
462 response["str_response_string"] = "";
463 response["keepalive"] = false;
464 response["reusecontext"] = false;
465
466 return response; 464 return response;
467 } 465 url = m_RequestMap[requestID];
466 startTime = url.requests[requestID].startTime;
467 }
468 468
469 urlData = m_RequestMap[requestID]; 469 if (System.Environment.TickCount - startTime > 25000)
470 {
471 response["int_response_code"] = 500;
472 response["str_response_string"] = "Script timeout";
473 response["content_type"] = "text/plain";
474 response["keepalive"] = false;
475 response["reusecontext"] = false;
470 476
471 if (System.Environment.TickCount - urlData.requests[requestID].startTime > 25000) 477 //remove from map
478 lock (url.requests)
479 {
480 url.requests.Remove(requestID);
481 }
482 lock (m_RequestMap)
472 { 483 {
473 response["int_response_code"] = 500;
474 response["str_response_string"] = "Script timeout";
475 response["content_type"] = "text/plain";
476 response["keepalive"] = false;
477 response["reusecontext"] = false;
478
479 //remove from map
480 urlData.requests.Remove(requestID);
481 m_RequestMap.Remove(requestID); 484 m_RequestMap.Remove(requestID);
482
483 return response;
484 } 485 }
486
487 return response;
485 } 488 }
486 489
490
487 return response; 491 return response;
488 } 492 }
489 493
490 private bool HasEvents(UUID requestID, UUID sessionID) 494 private bool HasEvents(UUID requestID, UUID sessionID)
491 { 495 {
492 lock (m_UrlMap) 496 UrlData url=null;
497
498 lock (m_RequestMap)
493 { 499 {
494 // We return true here because an external URL request that happened at the same time as an llRemoveURL()
495 // can still make it through to HttpRequestHandler(). That will return without setting up a request
496 // when it detects that the URL has been removed. The poller, however, will continue to ask for
497 // events for that request, so here we will signal that there are events and in GetEvents we will
498 // return a 404.
499 if (!m_RequestMap.ContainsKey(requestID)) 500 if (!m_RequestMap.ContainsKey(requestID))
500 { 501 {
501 return true; 502 return false;
502 } 503 }
503 504 url = m_RequestMap[requestID];
504 UrlData urlData = m_RequestMap[requestID]; 505 }
505 506 lock (url.requests)
506 if (!urlData.requests.ContainsKey(requestID)) 507 {
508 if (!url.requests.ContainsKey(requestID))
507 { 509 {
508 return true; 510 return false;
509 } 511 }
510 512 else
511 // Trigger return of timeout response.
512 if (System.Environment.TickCount - urlData.requests[requestID].startTime > 25000)
513 { 513 {
514 return true; 514 if (System.Environment.TickCount - url.requests[requestID].startTime > 25000)
515 {
516 return true;
517 }
518 if (url.requests[requestID].requestDone)
519 return true;
520 else
521 return false;
515 } 522 }
516
517 return urlData.requests[requestID].requestDone;
518 } 523 }
519 } 524 }
520
521 private Hashtable GetEvents(UUID requestID, UUID sessionID) 525 private Hashtable GetEvents(UUID requestID, UUID sessionID)
522 { 526 {
523 Hashtable response; 527 UrlData url = null;
528 RequestData requestData = null;
524 529
525 lock (m_UrlMap) 530 lock (m_RequestMap)
526 { 531 {
527 UrlData url = null;
528 RequestData requestData = null;
529
530 if (!m_RequestMap.ContainsKey(requestID)) 532 if (!m_RequestMap.ContainsKey(requestID))
531 return NoEvents(requestID, sessionID); 533 return NoEvents(requestID,sessionID);
532
533 url = m_RequestMap[requestID]; 534 url = m_RequestMap[requestID];
535 }
536 lock (url.requests)
537 {
534 requestData = url.requests[requestID]; 538 requestData = url.requests[requestID];
539 }
540
541 if (!requestData.requestDone)
542 return NoEvents(requestID,sessionID);
543
544 Hashtable response = new Hashtable();
535 545
536 if (!requestData.requestDone) 546 if (System.Environment.TickCount - requestData.startTime > 25000)
537 return NoEvents(requestID, sessionID); 547 {
538 548 response["int_response_code"] = 500;
539 response = new Hashtable(); 549 response["str_response_string"] = "Script timeout";
540 550 response["content_type"] = "text/plain";
541 if (System.Environment.TickCount - requestData.startTime > 25000)
542 {
543 response["int_response_code"] = 500;
544 response["str_response_string"] = "Script timeout";
545 response["content_type"] = "text/plain";
546 response["keepalive"] = false;
547 response["reusecontext"] = false;
548 return response;
549 }
550
551 //put response
552 response["int_response_code"] = requestData.responseCode;
553 response["str_response_string"] = requestData.responseBody;
554 response["content_type"] = requestData.responseType;
555 // response["content_type"] = "text/plain";
556 response["keepalive"] = false; 551 response["keepalive"] = false;
557 response["reusecontext"] = false; 552 response["reusecontext"] = false;
558 553 return response;
559 //remove from map 554 }
555 //put response
556 response["int_response_code"] = requestData.responseCode;
557 response["str_response_string"] = requestData.responseBody;
558 response["content_type"] = requestData.responseType;
559 response["keepalive"] = false;
560 response["reusecontext"] = false;
561
562 //remove from map
563 lock (url.requests)
564 {
560 url.requests.Remove(requestID); 565 url.requests.Remove(requestID);
566 }
567 lock (m_RequestMap)
568 {
561 m_RequestMap.Remove(requestID); 569 m_RequestMap.Remove(requestID);
562 } 570 }
563 571
@@ -566,41 +574,46 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
566 574
567 public void HttpRequestHandler(UUID requestID, Hashtable request) 575 public void HttpRequestHandler(UUID requestID, Hashtable request)
568 { 576 {
569 string uri = request["uri"].ToString(); 577 lock (request)
570 bool is_ssl = uri.Contains("lslhttps");
571
572 try
573 { 578 {
574 Hashtable headers = (Hashtable)request["headers"]; 579 string uri = request["uri"].ToString();
580 bool is_ssl = uri.Contains("lslhttps");
575 581
576// string uri_full = "http://" + m_ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + uri;// "/lslhttp/" + urlcode.ToString() + "/"; 582 try
583 {
584 Hashtable headers = (Hashtable)request["headers"];
577 585
578 int pos1 = uri.IndexOf("/");// /lslhttp 586// string uri_full = "http://" + ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + uri;// "/lslhttp/" + urlcode.ToString() + "/";
579 int pos2 = uri.IndexOf("/", pos1 + 1);// /lslhttp/
580 int pos3 = uri.IndexOf("/", pos2 + 1);// /lslhttp/<UUID>/
581 string uri_tmp = uri.Substring(0, pos3 + 1);
582 //HTTP server code doesn't provide us with QueryStrings
583 string pathInfo;
584 string queryString;
585 queryString = "";
586 587
587 pathInfo = uri.Substring(pos3); 588 int pos1 = uri.IndexOf("/");// /lslhttp
589 int pos2 = uri.IndexOf("/", pos1 + 1);// /lslhttp/
590 int pos3 = uri.IndexOf("/", pos2 + 1); // /lslhttp/urlcode
588 591
589 UrlData urlData = null; 592 string uri_tmp = uri.Substring(0, pos3 + 1);
593 //HTTP server code doesn't provide us with QueryStrings
594 string pathInfo;
595 string queryString;
596 queryString = "";
590 597
591 lock (m_UrlMap) 598 pathInfo = uri.Substring(pos3);
592 {
593 string url;
594 599
595 if (is_ssl) 600 UrlData url = null;
596 url = "https://" + ExternalHostNameForLSL + ":" + m_HttpsServer.Port.ToString() + uri_tmp; 601 string urlkey;
602 if (!is_ssl)
603 urlkey = "http://" + ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + uri_tmp;
604 //m_UrlMap[];
597 else 605 else
598 url = "http://" + ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + uri_tmp; 606 urlkey = "https://" + ExternalHostNameForLSL + ":" + m_HttpsServer.Port.ToString() + uri_tmp;
599 607
600 // Avoid a race - the request URL may have been released via llRequestUrl() whilst this 608 if (m_UrlMap.ContainsKey(urlkey))
601 // request was being processed. 609 {
602 if (!m_UrlMap.TryGetValue(url, out urlData)) 610 url = m_UrlMap[urlkey];
611 }
612 else
613 {
614 //m_log.Warn("[HttpRequestHandler]: http-in request failed; no such url: "+urlkey.ToString());
603 return; 615 return;
616 }
604 617
605 //for llGetHttpHeader support we need to store original URI here 618 //for llGetHttpHeader support we need to store original URI here
606 //to make x-path-info / x-query-string / x-script-url / x-remote-ip headers 619 //to make x-path-info / x-query-string / x-script-url / x-remote-ip headers
@@ -611,6 +624,8 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
611 requestData.requestDone = false; 624 requestData.requestDone = false;
612 requestData.startTime = System.Environment.TickCount; 625 requestData.startTime = System.Environment.TickCount;
613 requestData.uri = uri; 626 requestData.uri = uri;
627 requestData.hostID = url.hostID;
628 requestData.scene = url.scene;
614 if (requestData.headers == null) 629 if (requestData.headers == null)
615 requestData.headers = new Dictionary<string, string>(); 630 requestData.headers = new Dictionary<string, string>();
616 631
@@ -619,8 +634,33 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
619 string key = (string)header.Key; 634 string key = (string)header.Key;
620 string value = (string)header.Value; 635 string value = (string)header.Value;
621 requestData.headers.Add(key, value); 636 requestData.headers.Add(key, value);
637 if (key == "cookie")
638 {
639 string[] parts = value.Split(new char[] {'='});
640 if (parts[0] == "agni_sl_session_id" && parts.Length > 1)
641 {
642 string cookie = Uri.UnescapeDataString(parts[1]);
643 string[] crumbs = cookie.Split(new char[] {':'});
644 UUID owner;
645 if (crumbs.Length == 2 && UUID.TryParse(crumbs[0], out owner))
646 {
647 if (crumbs[1].Length == 32)
648 {
649 Scene scene = requestData.scene;
650 if (scene != null)
651 {
652 SceneObjectPart host = scene.GetSceneObjectPart(requestData.hostID);
653 if (host != null)
654 {
655 if (host.OwnerID == owner)
656 requestData.allowResponseType = true;
657 }
658 }
659 }
660 }
661 }
662 }
622 } 663 }
623
624 foreach (DictionaryEntry de in request) 664 foreach (DictionaryEntry de in request)
625 { 665 {
626 if (de.Key.ToString() == "querystringkeys") 666 if (de.Key.ToString() == "querystringkeys")
@@ -631,13 +671,21 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
631 if (request.ContainsKey(key)) 671 if (request.ContainsKey(key))
632 { 672 {
633 string val = (String)request[key]; 673 string val = (String)request[key];
634 queryString = queryString + key + "=" + val + "&"; 674 if (key != "")
675 {
676 queryString = queryString + key + "=" + val + "&";
677 }
678 else
679 {
680 queryString = queryString + val + "&";
681 }
635 } 682 }
636 } 683 }
637
638 if (queryString.Length > 1) 684 if (queryString.Length > 1)
639 queryString = queryString.Substring(0, queryString.Length - 1); 685 queryString = queryString.Substring(0, queryString.Length - 1);
686
640 } 687 }
688
641 } 689 }
642 690
643 //if this machine is behind DNAT/port forwarding, currently this is being 691 //if this machine is behind DNAT/port forwarding, currently this is being
@@ -645,23 +693,34 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
645 requestData.headers["x-remote-ip"] = requestData.headers["remote_addr"]; 693 requestData.headers["x-remote-ip"] = requestData.headers["remote_addr"];
646 requestData.headers["x-path-info"] = pathInfo; 694 requestData.headers["x-path-info"] = pathInfo;
647 requestData.headers["x-query-string"] = queryString; 695 requestData.headers["x-query-string"] = queryString;
648 requestData.headers["x-script-url"] = urlData.url; 696 requestData.headers["x-script-url"] = url.url;
649 697
650 urlData.requests.Add(requestID, requestData); 698 //requestData.ev = new ManualResetEvent(false);
651 m_RequestMap.Add(requestID, urlData); 699 lock (url.requests)
652 } 700 {
701 url.requests.Add(requestID, requestData);
702 }
703 lock (m_RequestMap)
704 {
705 //add to request map
706 m_RequestMap.Add(requestID, url);
707 }
653 708
654 urlData.engine.PostScriptEvent( 709 url.engine.PostScriptEvent(url.itemID, "http_request", new Object[] { requestID.ToString(), request["http-method"].ToString(), request["body"].ToString() });
655 urlData.itemID, 710
656 "http_request", 711 //send initial response?
657 new Object[] { requestID.ToString(), request["http-method"].ToString(), request["body"].ToString() }); 712// Hashtable response = new Hashtable();
658 } 713
659 catch (Exception we) 714 return;
660 { 715
661 //Hashtable response = new Hashtable(); 716 }
662 m_log.Warn("[HttpRequestHandler]: http-in request failed"); 717 catch (Exception we)
663 m_log.Warn(we.Message); 718 {
664 m_log.Warn(we.StackTrace); 719 //Hashtable response = new Hashtable();
720 m_log.Warn("[HttpRequestHandler]: http-in request failed");
721 m_log.Warn(we.Message);
722 m_log.Warn(we.StackTrace);
723 }
665 } 724 }
666 } 725 }
667 726
diff --git a/OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs b/OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs
index 6da2222..ad33f23 100644
--- a/OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs
@@ -271,6 +271,8 @@ namespace OpenSim.Region.CoreModules.Scripting.ScriptModuleComms
271 return "modInvokeR"; 271 return "modInvokeR";
272 else if (sid.ReturnType == typeof(object[])) 272 else if (sid.ReturnType == typeof(object[]))
273 return "modInvokeL"; 273 return "modInvokeL";
274 else if (sid.ReturnType == typeof(void))
275 return "modInvokeN";
274 276
275 m_log.WarnFormat("[MODULE COMMANDS] failed to find match for {0} with return type {1}",fname,sid.ReturnType.Name); 277 m_log.WarnFormat("[MODULE COMMANDS] failed to find match for {0} with return type {1}",fname,sid.ReturnType.Name);
276 } 278 }
diff --git a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs
index 4cecd85..2fc89fc 100644
--- a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs
@@ -861,4 +861,4 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
861 return null; 861 return null;
862 } 862 }
863 } 863 }
864} \ No newline at end of file 864}
diff --git a/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs b/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs
index 3484387..1a53a8b 100644
--- a/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs
@@ -96,6 +96,8 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
96 // private static readonly ILog m_log = 96 // private static readonly ILog m_log =
97 // LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 97 // LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
98 98
99 private const int DEBUG_CHANNEL = 2147483647;
100
99 private ListenerManager m_listenerManager; 101 private ListenerManager m_listenerManager;
100 private Queue m_pending; 102 private Queue m_pending;
101 private Queue m_pendingQ; 103 private Queue m_pendingQ;
@@ -366,61 +368,58 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
366 /// <param name='msg'> 368 /// <param name='msg'>
367 /// Message. 369 /// Message.
368 /// </param> 370 /// </param>
369 public void DeliverMessageTo(UUID target, int channel, Vector3 pos, 371 public bool DeliverMessageTo(UUID target, int channel, Vector3 pos, string name, UUID id, string msg)
370 string name, UUID id, string msg)
371 { 372 {
373 if (channel == DEBUG_CHANNEL)
374 return true;
375
372 // Is id an avatar? 376 // Is id an avatar?
373 ScenePresence sp = m_scene.GetScenePresence(target); 377 ScenePresence sp = m_scene.GetScenePresence(target);
374 378
375 if (sp != null) 379 if (sp != null)
376 { 380 {
377 // ignore if a child agent this is restricted to inside one 381 // Send message to avatar
378 // region 382 if (channel == 0)
379 if (sp.IsChildAgent)
380 return;
381
382 // Channel zero only goes to the avatar
383 // non zero channel messages only go to the attachments of the avatar.
384 if (channel != 0)
385 { 383 {
386 List<SceneObjectGroup> attachments = sp.GetAttachments(); 384 // Channel 0 goes to viewer ONLY
387 if (attachments.Count == 0) 385 m_scene.SimChat(Utils.StringToBytes(msg), ChatTypeEnum.Broadcast, 0, pos, name, id, target, false, false);
388 return; 386 return true;
387 }
389 388
390 // Get uuid of attachments 389 List<SceneObjectGroup> attachments = sp.GetAttachments();
391 List<UUID> targets = new List<UUID>();
392 foreach (SceneObjectGroup sog in attachments)
393 {
394 if (!sog.IsDeleted)
395 targets.Add(sog.UUID);
396 }
397 390
398 // Need to check each attachment 391 if (attachments.Count == 0)
399 foreach (ListenerInfo li 392 return true;
400 in m_listenerManager.GetListeners(UUID.Zero,
401 channel, name, id, msg))
402 {
403 if (li.GetHostID().Equals(id))
404 continue;
405 393
406 if (m_scene.GetSceneObjectPart( 394 // Get uuid of attachments
407 li.GetHostID()) == null) 395 List<UUID> targets = new List<UUID>();
408 { 396 foreach (SceneObjectGroup sog in attachments)
409 continue; 397 {
410 } 398 if (!sog.IsDeleted)
399 targets.Add(sog.UUID);
400 }
411 401
412 if (targets.Contains(li.GetHostID())) 402 // Need to check each attachment
413 QueueMessage(new ListenerInfo(li, name, id, msg)); 403 foreach (ListenerInfo li in m_listenerManager.GetListeners(UUID.Zero, channel, name, id, msg))
414 } 404 {
405 if (li.GetHostID().Equals(id))
406 continue;
407
408 if (m_scene.GetSceneObjectPart(li.GetHostID()) == null)
409 continue;
410
411 if (targets.Contains(li.GetHostID()))
412 QueueMessage(new ListenerInfo(li, name, id, msg));
415 } 413 }
416 414
417 return; 415 return true;
418 } 416 }
419 417
420 // No avatar found so look for an object 418 SceneObjectPart part = m_scene.GetSceneObjectPart(target);
421 foreach (ListenerInfo li 419 if (part == null) // Not even an object
422 in m_listenerManager.GetListeners(UUID.Zero, channel, 420 return true; // No error
423 name, id, msg)) 421
422 foreach (ListenerInfo li in m_listenerManager.GetListeners(UUID.Zero, channel, name, id, msg))
424 { 423 {
425 // Dont process if this message is from yourself! 424 // Dont process if this message is from yourself!
426 if (li.GetHostID().Equals(id)) 425 if (li.GetHostID().Equals(id))
@@ -438,7 +437,7 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
438 } 437 }
439 } 438 }
440 439
441 return; 440 return true;
442 } 441 }
443 442
444 protected void QueueMessage(ListenerInfo li) 443 protected void QueueMessage(ListenerInfo li)