aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/Scripting
diff options
context:
space:
mode:
authoronefang2019-05-19 21:24:15 +1000
committeronefang2019-05-19 21:24:15 +1000
commit5e4d6cab00cb29cd088ab7b62ab13aff103b64cb (patch)
treea9fbc62df9eb2d1d9ba2698d8552eae71eca20d8 /OpenSim/Region/CoreModules/Scripting
parentAdd a build script. (diff)
downloadopensim-SC_OLD-5e4d6cab00cb29cd088ab7b62ab13aff103b64cb.zip
opensim-SC_OLD-5e4d6cab00cb29cd088ab7b62ab13aff103b64cb.tar.gz
opensim-SC_OLD-5e4d6cab00cb29cd088ab7b62ab13aff103b64cb.tar.bz2
opensim-SC_OLD-5e4d6cab00cb29cd088ab7b62ab13aff103b64cb.tar.xz
Dump OpenSim 0.9.0.1 into it's own branch.
Diffstat (limited to 'OpenSim/Region/CoreModules/Scripting')
-rw-r--r--OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs147
-rw-r--r--OpenSim/Region/CoreModules/Scripting/EMailModules/EmailModule.cs31
-rw-r--r--OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs259
-rw-r--r--OpenSim/Region/CoreModules/Scripting/HttpRequest/Tests/ScriptsHttpRequestsTests.cs22
-rw-r--r--OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs542
-rw-r--r--OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs56
-rw-r--r--OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs10
-rw-r--r--OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs48
-rw-r--r--OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs122
-rw-r--r--OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs124
-rw-r--r--OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs6
11 files changed, 793 insertions, 574 deletions
diff --git a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs
index a686a4d..090cb7d 100644
--- a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs
@@ -135,17 +135,13 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
135 m_reuseableDynamicTextures.Store( 135 m_reuseableDynamicTextures.Store(
136 GenerateReusableTextureKey(texture.InputCommands, texture.InputParams), newTextureID); 136 GenerateReusableTextureKey(texture.InputCommands, texture.InputParams), newTextureID);
137 } 137 }
138 updater.newTextureID = newTextureID;
138 } 139 }
139 }
140 140
141 if (updater.UpdateTimer == 0)
142 {
143 lock (Updaters) 141 lock (Updaters)
144 { 142 {
145 if (!Updaters.ContainsKey(updater.UpdaterID)) 143 if (Updaters.ContainsKey(updater.UpdaterID))
146 {
147 Updaters.Remove(updater.UpdaterID); 144 Updaters.Remove(updater.UpdaterID);
148 }
149 } 145 }
150 } 146 }
151 } 147 }
@@ -172,21 +168,20 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
172 } 168 }
173 169
174 public UUID AddDynamicTextureURL(UUID simID, UUID primID, string contentType, string url, 170 public UUID AddDynamicTextureURL(UUID simID, UUID primID, string contentType, string url,
175 string extraParams, int updateTimer) 171 string extraParams)
176 { 172 {
177 return AddDynamicTextureURL(simID, primID, contentType, url, extraParams, updateTimer, false, 255); 173 return AddDynamicTextureURL(simID, primID, contentType, url, extraParams, false, 255);
178 } 174 }
179 175
180 public UUID AddDynamicTextureURL(UUID simID, UUID primID, string contentType, string url, 176 public UUID AddDynamicTextureURL(UUID simID, UUID primID, string contentType, string url,
181 string extraParams, int updateTimer, bool SetBlending, byte AlphaValue) 177 string extraParams, bool SetBlending, byte AlphaValue)
182 { 178 {
183 return AddDynamicTextureURL(simID, primID, contentType, url, 179 return AddDynamicTextureURL(simID, primID, contentType, url, extraParams, SetBlending,
184 extraParams, updateTimer, SetBlending, 180 (DISP_TEMP|DISP_EXPIRE), AlphaValue, ALL_SIDES);
185 (int)(DISP_TEMP|DISP_EXPIRE), AlphaValue, ALL_SIDES);
186 } 181 }
187 182
188 public UUID AddDynamicTextureURL(UUID simID, UUID primID, string contentType, string url, 183 public UUID AddDynamicTextureURL(UUID simID, UUID primID, string contentType, string url,
189 string extraParams, int updateTimer, bool SetBlending, 184 string extraParams, bool SetBlending,
190 int disp, byte AlphaValue, int face) 185 int disp, byte AlphaValue, int face)
191 { 186 {
192 if (RenderPlugins.ContainsKey(contentType)) 187 if (RenderPlugins.ContainsKey(contentType))
@@ -196,7 +191,6 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
196 updater.PrimID = primID; 191 updater.PrimID = primID;
197 updater.ContentType = contentType; 192 updater.ContentType = contentType;
198 updater.Url = url; 193 updater.Url = url;
199 updater.UpdateTimer = updateTimer;
200 updater.UpdaterID = UUID.Random(); 194 updater.UpdaterID = UUID.Random();
201 updater.Params = extraParams; 195 updater.Params = extraParams;
202 updater.BlendWithOldTexture = SetBlending; 196 updater.BlendWithOldTexture = SetBlending;
@@ -213,26 +207,27 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
213 } 207 }
214 208
215 RenderPlugins[contentType].AsyncConvertUrl(updater.UpdaterID, url, extraParams); 209 RenderPlugins[contentType].AsyncConvertUrl(updater.UpdaterID, url, extraParams);
216 return updater.UpdaterID; 210 return updater.newTextureID;
217 } 211 }
218 return UUID.Zero; 212 return UUID.Zero;
219 } 213 }
220 214
221 public UUID AddDynamicTextureData(UUID simID, UUID primID, string contentType, string data, 215 public UUID AddDynamicTextureData(UUID simID, UUID primID, string contentType, string data,
222 string extraParams, int updateTimer) 216 string extraParams)
223 { 217 {
224 return AddDynamicTextureData(simID, primID, contentType, data, extraParams, updateTimer, false, 255); 218 return AddDynamicTextureData(simID, primID, contentType, data, extraParams, false,
219 (DISP_TEMP|DISP_EXPIRE), 255, ALL_SIDES);
225 } 220 }
226 221
227 public UUID AddDynamicTextureData(UUID simID, UUID primID, string contentType, string data, 222 public UUID AddDynamicTextureData(UUID simID, UUID primID, string contentType, string data,
228 string extraParams, int updateTimer, bool SetBlending, byte AlphaValue) 223 string extraParams, bool SetBlending, byte AlphaValue)
229 { 224 {
230 return AddDynamicTextureData(simID, primID, contentType, data, extraParams, updateTimer, SetBlending, 225 return AddDynamicTextureData(simID, primID, contentType, data, extraParams, SetBlending,
231 (int) (DISP_TEMP|DISP_EXPIRE), AlphaValue, ALL_SIDES); 226 (DISP_TEMP|DISP_EXPIRE), AlphaValue, ALL_SIDES);
232 } 227 }
233 228
234 public UUID AddDynamicTextureData(UUID simID, UUID primID, string contentType, string data, 229 public UUID AddDynamicTextureData(UUID simID, UUID primID, string contentType, string data,
235 string extraParams, int updateTimer, bool SetBlending, int disp, byte AlphaValue, int face) 230 string extraParams, bool SetBlending, int disp, byte AlphaValue, int face)
236 { 231 {
237 if (!RenderPlugins.ContainsKey(contentType)) 232 if (!RenderPlugins.ContainsKey(contentType))
238 return UUID.Zero; 233 return UUID.Zero;
@@ -258,7 +253,6 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
258 updater.PrimID = primID; 253 updater.PrimID = primID;
259 updater.ContentType = contentType; 254 updater.ContentType = contentType;
260 updater.BodyData = data; 255 updater.BodyData = data;
261 updater.UpdateTimer = updateTimer;
262 updater.UpdaterID = UUID.Random(); 256 updater.UpdaterID = UUID.Random();
263 updater.Params = extraParams; 257 updater.Params = extraParams;
264 updater.BlendWithOldTexture = SetBlending; 258 updater.BlendWithOldTexture = SetBlending;
@@ -314,7 +308,7 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
314 updater.UpdatePart(part, (UUID)objReusableTextureUUID); 308 updater.UpdatePart(part, (UUID)objReusableTextureUUID);
315 } 309 }
316 310
317 return updater.UpdaterID; 311 return updater.newTextureID;
318 } 312 }
319 313
320 private string GenerateReusableTextureKey(string data, string extraParams) 314 private string GenerateReusableTextureKey(string data, string extraParams)
@@ -404,17 +398,15 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
404 public byte FrontAlpha = 255; 398 public byte FrontAlpha = 255;
405 public string Params; 399 public string Params;
406 public UUID PrimID; 400 public UUID PrimID;
407 public bool SetNewFrontAlpha = false;
408 public UUID SimUUID; 401 public UUID SimUUID;
409 public UUID UpdaterID; 402 public UUID UpdaterID;
410 public int UpdateTimer;
411 public int Face; 403 public int Face;
412 public int Disp; 404 public int Disp;
413 public string Url; 405 public string Url;
406 public UUID newTextureID;
414 407
415 public DynamicTextureUpdater() 408 public DynamicTextureUpdater()
416 { 409 {
417 UpdateTimer = 0;
418 BodyData = null; 410 BodyData = null;
419 } 411 }
420 412
@@ -436,16 +428,23 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
436 // FIXME: Need to return the appropriate ID if only a single face is replaced. 428 // FIXME: Need to return the appropriate ID if only a single face is replaced.
437 oldID = tmptex.DefaultTexture.TextureID; 429 oldID = tmptex.DefaultTexture.TextureID;
438 430
431 // not using parts number of faces because that fails on old meshs
439 if (Face == ALL_SIDES) 432 if (Face == ALL_SIDES)
440 { 433 {
441 oldID = tmptex.DefaultTexture.TextureID; 434 oldID = tmptex.DefaultTexture.TextureID;
442 tmptex.DefaultTexture.TextureID = textureID; 435 tmptex.DefaultTexture.TextureID = textureID;
436 for(int i = 0; i < tmptex.FaceTextures.Length; i++)
437 {
438 if(tmptex.FaceTextures[i] != null)
439 tmptex.FaceTextures[i].TextureID = textureID;
440 }
443 } 441 }
444 else 442 else
445 { 443 {
446 try 444 try
447 { 445 {
448 Primitive.TextureEntryFace texface = tmptex.CreateFace((uint)Face); 446 Primitive.TextureEntryFace texface = tmptex.CreateFace((uint)Face);
447 oldID = texface.TextureID;
449 texface.TextureID = textureID; 448 texface.TextureID = textureID;
450 tmptex.FaceTextures[Face] = texface; 449 tmptex.FaceTextures[Face] = texface;
451 } 450 }
@@ -455,10 +454,6 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
455 } 454 }
456 } 455 }
457 456
458 // I'm pretty sure we always want to force this to true
459 // I'm pretty sure noone whats to set fullbright true if it wasn't true before.
460 // tmptex.DefaultTexture.Fullbright = true;
461
462 part.UpdateTextureEntry(tmptex.GetBytes()); 457 part.UpdateTextureEntry(tmptex.GetBytes());
463 } 458 }
464 459
@@ -478,26 +473,39 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
478 473
479 if (part == null || data == null || data.Length <= 1) 474 if (part == null || data == null || data.Length <= 1)
480 { 475 {
481 string msg = 476 string msg =
482 String.Format("DynamicTextureModule: Error preparing image using URL {0}", Url); 477 String.Format("DynamicTextureModule: Error preparing image using URL {0}", Url);
483 scene.SimChat(Utils.StringToBytes(msg), ChatTypeEnum.Say, 478 scene.SimChat(Utils.StringToBytes(msg), ChatTypeEnum.Say,
484 0, part.ParentGroup.RootPart.AbsolutePosition, part.Name, part.UUID, false); 479 0, part.ParentGroup.RootPart.AbsolutePosition, part.Name, part.UUID, false);
485 480
486 return UUID.Zero; 481 return UUID.Zero;
487 } 482 }
488 483
489 byte[] assetData = null; 484 byte[] assetData = null;
490 AssetBase oldAsset = null; 485 AssetBase oldAsset = null;
491 486
492 if (BlendWithOldTexture) 487 if (BlendWithOldTexture)
493 { 488 {
494 Primitive.TextureEntryFace defaultFace = part.Shape.Textures.DefaultTexture; 489 Primitive.TextureEntryFace curFace;
495 if (defaultFace != null) 490 if(Face == ALL_SIDES)
491 curFace = part.Shape.Textures.DefaultTexture;
492 else
496 { 493 {
497 oldAsset = scene.AssetService.Get(defaultFace.TextureID.ToString()); 494 try
495 {
496 curFace = part.Shape.Textures.GetFace((uint)Face);
497 }
498 catch
499 {
500 curFace = null;
501 }
502 }
503 if (curFace != null)
504 {
505 oldAsset = scene.AssetService.Get(curFace.TextureID.ToString());
498 506
499 if (oldAsset != null) 507 if (oldAsset != null)
500 assetData = BlendTextures(data, oldAsset.Data, SetNewFrontAlpha, FrontAlpha); 508 assetData = BlendTextures(data, oldAsset.Data, FrontAlpha);
501 } 509 }
502 } 510 }
503 511
@@ -548,42 +556,49 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
548 return asset.FullID; 556 return asset.FullID;
549 } 557 }
550 558
551 private byte[] BlendTextures(byte[] frontImage, byte[] backImage, bool setNewAlpha, byte newAlpha) 559 private byte[] BlendTextures(byte[] frontImage, byte[] backImage, byte newAlpha)
552 { 560 {
553 ManagedImage managedImage; 561 ManagedImage managedImage;
554 Image image; 562 Image image;
555 563
556 if (OpenJPEG.DecodeToImage(frontImage, out managedImage, out image)) 564 if (!OpenJPEG.DecodeToImage(frontImage, out managedImage, out image) || image == null)
565 return null;
566
567 Bitmap image1 = new Bitmap(image);
568 image.Dispose();
569
570 if (!OpenJPEG.DecodeToImage(backImage, out managedImage, out image) || image == null)
557 { 571 {
558 Bitmap image1 = new Bitmap(image); 572 image1.Dispose();
573 return null;
574 }
559 575
560 if (OpenJPEG.DecodeToImage(backImage, out managedImage, out image)) 576 Bitmap image2 = new Bitmap(image);
561 { 577 image.Dispose();
562 Bitmap image2 = new Bitmap(image);
563 578
564 if (setNewAlpha) 579 if (newAlpha < 255)
565 SetAlpha(ref image1, newAlpha); 580 SetAlpha(ref image1, newAlpha);
566 581
567 Bitmap joint = MergeBitMaps(image1, image2); 582 using(Bitmap joint = MergeBitMaps(image1, image2))
583 {
584 image1.Dispose();
585 image2.Dispose();
568 586
569 byte[] result = new byte[0]; 587 byte[] result = new byte[0];
570 588
571 try 589 try
572 { 590 {
573 result = OpenJPEG.EncodeFromImage(joint, true); 591 result = OpenJPEG.EncodeFromImage(joint, true);
574 } 592 }
575 catch (Exception e) 593 catch (Exception e)
576 { 594 {
577 m_log.ErrorFormat( 595 m_log.ErrorFormat(
578 "[DYNAMICTEXTUREMODULE]: OpenJpeg Encode Failed. Exception {0}{1}", 596 "[DYNAMICTEXTUREMODULE]: OpenJpeg Encode Failed. Exception {0}{1}",
579 e.Message, e.StackTrace); 597 e.Message, e.StackTrace);
580 }
581
582 return result;
583 } 598 }
584 }
585 599
586 return null; 600 return result;
601 }
587 } 602 }
588 603
589 public Bitmap MergeBitMaps(Bitmap front, Bitmap back) 604 public Bitmap MergeBitMaps(Bitmap front, Bitmap back)
@@ -592,12 +607,12 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
592 Graphics jG; 607 Graphics jG;
593 608
594 joint = new Bitmap(back.Width, back.Height, PixelFormat.Format32bppArgb); 609 joint = new Bitmap(back.Width, back.Height, PixelFormat.Format32bppArgb);
595 jG = Graphics.FromImage(joint); 610 using(jG = Graphics.FromImage(joint))
596 611 {
597 jG.DrawImage(back, 0, 0, back.Width, back.Height); 612 jG.DrawImage(back, 0, 0, back.Width, back.Height);
598 jG.DrawImage(front, 0, 0, back.Width, back.Height); 613 jG.DrawImage(front, 0, 0, back.Width, back.Height);
599 614 return joint;
600 return joint; 615 }
601 } 616 }
602 617
603 private void SetAlpha(ref Bitmap b, byte alpha) 618 private void SetAlpha(ref Bitmap b, byte alpha)
diff --git a/OpenSim/Region/CoreModules/Scripting/EMailModules/EmailModule.cs b/OpenSim/Region/CoreModules/Scripting/EMailModules/EmailModule.cs
index 4e7ad75..d59cfa9 100644
--- a/OpenSim/Region/CoreModules/Scripting/EMailModules/EmailModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/EMailModules/EmailModule.cs
@@ -113,7 +113,7 @@ namespace OpenSim.Region.CoreModules.Scripting.EmailModules
113 } 113 }
114 catch (Exception e) 114 catch (Exception e)
115 { 115 {
116 m_log.Error("[EMAIL] DefaultEmailModule not configured: " + e.Message); 116 m_log.Error("[EMAIL]: DefaultEmailModule not configured: " + e.Message);
117 m_Enabled = false; 117 m_Enabled = false;
118 return; 118 return;
119 } 119 }
@@ -142,7 +142,7 @@ namespace OpenSim.Region.CoreModules.Scripting.EmailModules
142 } 142 }
143 } 143 }
144 144
145 m_log.Info("[EMAIL] Activated DefaultEmailModule"); 145 m_log.Info("[EMAIL]: Activated DefaultEmailModule");
146 } 146 }
147 147
148 public void RemoveRegion(Scene scene) 148 public void RemoveRegion(Scene scene)
@@ -224,8 +224,9 @@ namespace OpenSim.Region.CoreModules.Scripting.EmailModules
224 return null; 224 return null;
225 } 225 }
226 226
227 private void resolveNamePositionRegionName(UUID objectID, out string ObjectName, out string ObjectAbsolutePosition, out string ObjectRegionName) 227 private bool resolveNamePositionRegionName(UUID objectID, out string ObjectName, out string ObjectAbsolutePosition, out string ObjectRegionName)
228 { 228 {
229 ObjectName = ObjectAbsolutePosition = ObjectRegionName = String.Empty;
229 string m_ObjectRegionName; 230 string m_ObjectRegionName;
230 int objectLocX; 231 int objectLocX;
231 int objectLocY; 232 int objectLocY;
@@ -239,15 +240,9 @@ namespace OpenSim.Region.CoreModules.Scripting.EmailModules
239 ObjectAbsolutePosition = "(" + objectLocX + ", " + objectLocY + ", " + objectLocZ + ")"; 240 ObjectAbsolutePosition = "(" + objectLocX + ", " + objectLocY + ", " + objectLocZ + ")";
240 ObjectName = part.Name; 241 ObjectName = part.Name;
241 ObjectRegionName = m_ObjectRegionName; 242 ObjectRegionName = m_ObjectRegionName;
242 return; 243 return true;
243 } 244 }
244 objectLocX = (int)part.AbsolutePosition.X; 245 return false;
245 objectLocY = (int)part.AbsolutePosition.Y;
246 objectLocZ = (int)part.AbsolutePosition.Z;
247 ObjectAbsolutePosition = "(" + objectLocX + ", " + objectLocY + ", " + objectLocZ + ")";
248 ObjectName = part.Name;
249 ObjectRegionName = m_ObjectRegionName;
250 return;
251 } 246 }
252 247
253 /// <summary> 248 /// <summary>
@@ -273,12 +268,12 @@ namespace OpenSim.Region.CoreModules.Scripting.EmailModules
273 bool isEMailStrictMatch = EMailreStrict.IsMatch(address); 268 bool isEMailStrictMatch = EMailreStrict.IsMatch(address);
274 if (!isEMailStrictMatch) 269 if (!isEMailStrictMatch)
275 { 270 {
276 m_log.Error("[EMAIL] REGEX Problem in EMail Address: "+address); 271 m_log.Error("[EMAIL]: REGEX Problem in EMail Address: "+address);
277 return; 272 return;
278 } 273 }
279 if ((subject.Length + body.Length) > m_MaxEmailSize) 274 if ((subject.Length + body.Length) > m_MaxEmailSize)
280 { 275 {
281 m_log.Error("[EMAIL] subject + body larger than limit of " + m_MaxEmailSize + " bytes"); 276 m_log.Error("[EMAIL]: subject + body larger than limit of " + m_MaxEmailSize + " bytes");
282 return; 277 return;
283 } 278 }
284 279
@@ -286,7 +281,8 @@ namespace OpenSim.Region.CoreModules.Scripting.EmailModules
286 string LastObjectPosition = string.Empty; 281 string LastObjectPosition = string.Empty;
287 string LastObjectRegionName = string.Empty; 282 string LastObjectRegionName = string.Empty;
288 283
289 resolveNamePositionRegionName(objectID, out LastObjectName, out LastObjectPosition, out LastObjectRegionName); 284 if (!resolveNamePositionRegionName(objectID, out LastObjectName, out LastObjectPosition, out LastObjectRegionName))
285 return;
290 286
291 if (!address.EndsWith(m_InterObjectHostname)) 287 if (!address.EndsWith(m_InterObjectHostname))
292 { 288 {
@@ -302,7 +298,8 @@ namespace OpenSim.Region.CoreModules.Scripting.EmailModules
302 //Subject 298 //Subject
303 emailMessage.Subject = subject; 299 emailMessage.Subject = subject;
304 //TEXT Body 300 //TEXT Body
305 resolveNamePositionRegionName(objectID, out LastObjectName, out LastObjectPosition, out LastObjectRegionName); 301 if (!resolveNamePositionRegionName(objectID, out LastObjectName, out LastObjectPosition, out LastObjectRegionName))
302 return;
306 emailMessage.BodyText = "Object-Name: " + LastObjectName + 303 emailMessage.BodyText = "Object-Name: " + LastObjectName +
307 "\nRegion: " + LastObjectRegionName + "\nLocal-Position: " + 304 "\nRegion: " + LastObjectRegionName + "\nLocal-Position: " +
308 LastObjectPosition + "\n\n" + body; 305 LastObjectPosition + "\n\n" + body;
@@ -321,11 +318,11 @@ namespace OpenSim.Region.CoreModules.Scripting.EmailModules
321 emailMessage.Send(smtpServer); 318 emailMessage.Send(smtpServer);
322 319
323 //Log 320 //Log
324 m_log.Info("[EMAIL] EMail sent to: " + address + " from object: " + objectID.ToString() + "@" + m_HostName); 321 m_log.Info("[EMAIL]: EMail sent to: " + address + " from object: " + objectID.ToString() + "@" + m_HostName);
325 } 322 }
326 catch (Exception e) 323 catch (Exception e)
327 { 324 {
328 m_log.Error("[EMAIL] DefaultEmailModule Exception: " + e.Message); 325 m_log.Error("[EMAIL]: DefaultEmailModule Exception: " + e.Message);
329 } 326 }
330 } 327 }
331 else 328 else
diff --git a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs
index 9dfeb96..f5b575b 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 {
@@ -191,7 +190,15 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
191 190
192 case (int)HttpRequestConstants.HTTP_BODY_MAXLENGTH: 191 case (int)HttpRequestConstants.HTTP_BODY_MAXLENGTH:
193 192
194 // TODO implement me 193 int len;
194 if(int.TryParse(parms[i + 1], out len))
195 {
196 if(len > HttpRequestClass.HttpBodyMaxLenMAX)
197 len = HttpRequestClass.HttpBodyMaxLenMAX;
198 else if(len < 64) //???
199 len = 64;
200 htc.HttpBodyMaxLen = len;
201 }
195 break; 202 break;
196 203
197 case (int)HttpRequestConstants.HTTP_VERIFY_CERT: 204 case (int)HttpRequestConstants.HTTP_VERIFY_CERT:
@@ -216,20 +223,16 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
216 if (parms.Length - i < 2) 223 if (parms.Length - i < 2)
217 break; 224 break;
218 225
219 //Have we reached the end of the list of headers?
220 //End is marked by a string with a single digit.
221 //We already know we have at least one parameter
222 //so it is safe to do this check at top of loop.
223 if (Char.IsDigit(parms[i][0]))
224 break;
225
226 if (htc.HttpCustomHeaders == null) 226 if (htc.HttpCustomHeaders == null)
227 htc.HttpCustomHeaders = new List<string>(); 227 htc.HttpCustomHeaders = new List<string>();
228 228
229 htc.HttpCustomHeaders.Add(parms[i]); 229 htc.HttpCustomHeaders.Add(parms[i]);
230 htc.HttpCustomHeaders.Add(parms[i+1]); 230 htc.HttpCustomHeaders.Add(parms[i+1]);
231 int nexti = i + 2;
232 if (nexti >= parms.Length || Char.IsDigit(parms[nexti][0]))
233 break;
231 234
232 i += 2; 235 i = nexti;
233 } 236 }
234 break; 237 break;
235 238
@@ -239,7 +242,7 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
239 } 242 }
240 } 243 }
241 } 244 }
242 245
243 htc.RequestModule = this; 246 htc.RequestModule = this;
244 htc.LocalID = localID; 247 htc.LocalID = localID;
245 htc.ItemID = itemID; 248 htc.ItemID = itemID;
@@ -276,7 +279,7 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
276 } 279 }
277 280
278 public bool StartHttpRequest(HttpRequestClass req) 281 public bool StartHttpRequest(HttpRequestClass req)
279 { 282 {
280 if (!CheckAllowed(new Uri(req.Url))) 283 if (!CheckAllowed(new Uri(req.Url)))
281 return false; 284 return false;
282 285
@@ -290,29 +293,18 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
290 return true; 293 return true;
291 } 294 }
292 295
293 public void StopHttpRequestsForScript(UUID id) 296 public void StopHttpRequest(uint m_localID, UUID m_itemID)
294 { 297 {
295 if (m_pendingRequests != null) 298 if (m_pendingRequests != null)
296 { 299 {
297 List<UUID> keysToRemove = null;
298
299 lock (HttpListLock) 300 lock (HttpListLock)
300 { 301 {
301 foreach (HttpRequestClass req in m_pendingRequests.Values) 302 HttpRequestClass tmpReq;
303 if (m_pendingRequests.TryGetValue(m_itemID, out tmpReq))
302 { 304 {
303 if (req.ItemID == id) 305 tmpReq.Stop();
304 { 306 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 } 307 }
313
314 if (keysToRemove != null)
315 keysToRemove.ForEach(keyToRemove => m_pendingRequests.Remove(keyToRemove));
316 } 308 }
317 } 309 }
318 } 310 }
@@ -330,13 +322,19 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
330 { 322 {
331 lock (HttpListLock) 323 lock (HttpListLock)
332 { 324 {
333 foreach (HttpRequestClass req in m_pendingRequests.Values) 325 foreach (UUID luid in m_pendingRequests.Keys)
334 { 326 {
335 if (req.Finished) 327 HttpRequestClass tmpReq;
336 return req; 328
329 if (m_pendingRequests.TryGetValue(luid, out tmpReq))
330 {
331 if (tmpReq.Finished)
332 {
333 return tmpReq;
334 }
335 }
337 } 336 }
338 } 337 }
339
340 return null; 338 return null;
341 } 339 }
342 340
@@ -363,9 +361,34 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
363 m_proxyurl = config.Configs["Startup"].GetString("HttpProxy"); 361 m_proxyurl = config.Configs["Startup"].GetString("HttpProxy");
364 m_proxyexcepts = config.Configs["Startup"].GetString("HttpProxyExceptions"); 362 m_proxyexcepts = config.Configs["Startup"].GetString("HttpProxyExceptions");
365 363
364 HttpRequestClass.HttpBodyMaxLenMAX = config.Configs["Network"].GetInt("HttpBodyMaxLenMAX", 16384);
365
366
366 m_outboundUrlFilter = new OutboundUrlFilter("Script HTTP request module", config); 367 m_outboundUrlFilter = new OutboundUrlFilter("Script HTTP request module", config);
368 int maxThreads = 15;
369
370 IConfig httpConfig = config.Configs["HttpRequestModule"];
371 if (httpConfig != null)
372 {
373 maxThreads = httpConfig.GetInt("MaxPoolThreads", maxThreads);
374 }
367 375
368 m_pendingRequests = new Dictionary<UUID, HttpRequestClass>(); 376 m_pendingRequests = new Dictionary<UUID, HttpRequestClass>();
377
378 // First instance sets this up for all sims
379 if (ThreadPool == null)
380 {
381 STPStartInfo startInfo = new STPStartInfo();
382 startInfo.IdleTimeout = 2000;
383 startInfo.MaxWorkerThreads = maxThreads;
384 startInfo.MinWorkerThreads = 0;
385 startInfo.ThreadPriority = ThreadPriority.BelowNormal;
386 startInfo.StartSuspended = true;
387 startInfo.ThreadPoolName = "ScriptsHttpReq";
388
389 ThreadPool = new SmartThreadPool(startInfo);
390 ThreadPool.Start();
391 }
369 } 392 }
370 393
371 public void AddRegion(Scene scene) 394 public void AddRegion(Scene scene)
@@ -392,6 +415,7 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
392 415
393 public void Close() 416 public void Close()
394 { 417 {
418 ThreadPool.Shutdown();
395 } 419 }
396 420
397 public string Name 421 public string Name
@@ -409,8 +433,6 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
409 433
410 public class HttpRequestClass : IServiceRequest 434 public class HttpRequestClass : IServiceRequest
411 { 435 {
412// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
413
414 // Constants for parameters 436 // Constants for parameters
415 // public const int HTTP_BODY_MAXLENGTH = 2; 437 // public const int HTTP_BODY_MAXLENGTH = 2;
416 // public const int HTTP_METHOD = 0; 438 // public const int HTTP_METHOD = 0;
@@ -430,13 +452,17 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
430 { 452 {
431 get { return _finished; } 453 get { return _finished; }
432 } 454 }
433 // public int HttpBodyMaxLen = 2048; // not implemented 455
456 public static int HttpBodyMaxLenMAX = 16384;
434 457
435 // Parameter members and default values 458 // Parameter members and default values
459 public int HttpBodyMaxLen = 2048;
436 public string HttpMethod = "GET"; 460 public string HttpMethod = "GET";
437 public string HttpMIMEType = "text/plain;charset=utf-8"; 461 public string HttpMIMEType = "text/plain;charset=utf-8";
438 public int HttpTimeout; 462 public int HttpTimeout;
439 public bool HttpVerifyCert = true; 463 public bool HttpVerifyCert = true;
464 public IWorkItemResult WorkItem = null;
465
440 //public bool HttpVerboseThrottle = true; // not implemented 466 //public bool HttpVerboseThrottle = true; // not implemented
441 public List<string> HttpCustomHeaders = null; 467 public List<string> HttpCustomHeaders = null;
442 public bool HttpPragmaNoCache = true; 468 public bool HttpPragmaNoCache = true;
@@ -484,15 +510,40 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
484 510
485 public void Process() 511 public void Process()
486 { 512 {
513 _finished = false;
514
515 lock (HttpRequestModule.ThreadPool)
516 WorkItem = HttpRequestModule.ThreadPool.QueueWorkItem(new WorkItemCallback(StpSendWrapper), null);
517 }
518
519 private object StpSendWrapper(object o)
520 {
487 SendRequest(); 521 SendRequest();
522 return null;
488 } 523 }
489 524
525 /*
526 * TODO: More work on the response codes. Right now
527 * returning 200 for success or 499 for exception
528 */
529
490 public void SendRequest() 530 public void SendRequest()
491 { 531 {
532 HttpWebResponse response = null;
533 Stream resStream = null;
534 byte[] buf = new byte[HttpBodyMaxLenMAX + 16];
535 string tempString = null;
536 int count = 0;
537
492 try 538 try
493 { 539 {
494 Request = (HttpWebRequest)WebRequest.Create(Url); 540 Request = (HttpWebRequest)WebRequest.Create(Url);
495 Request.AllowAutoRedirect = false; 541 Request.AllowAutoRedirect = false;
542 Request.KeepAlive = false;
543
544 //This works around some buggy HTTP Servers like Lighttpd
545 Request.ServicePoint.Expect100Continue = false;
546
496 Request.Method = HttpMethod; 547 Request.Method = HttpMethod;
497 Request.ContentType = HttpMIMEType; 548 Request.ContentType = HttpMIMEType;
498 549
@@ -500,7 +551,6 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
500 { 551 {
501 // We could hijack Connection Group Name to identify 552 // We could hijack Connection Group Name to identify
502 // a desired security exception. But at the moment we'll use a dummy header instead. 553 // 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"); 554 Request.Headers.Add("NoVerifyCert", "true");
505 } 555 }
506// else 556// else
@@ -533,14 +583,11 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
533 } 583 }
534 } 584 }
535 585
536 if (ResponseHeaders != null) 586 foreach (KeyValuePair<string, string> entry in ResponseHeaders)
537 { 587 if (entry.Key.ToLower().Equals("user-agent"))
538 foreach (KeyValuePair<string, string> entry in ResponseHeaders) 588 Request.UserAgent = entry.Value;
539 if (entry.Key.ToLower().Equals("user-agent") && Request is HttpWebRequest) 589 else
540 ((HttpWebRequest)Request).UserAgent = entry.Value; 590 Request.Headers[entry.Key] = entry.Value;
541 else
542 Request.Headers[entry.Key] = entry.Value;
543 }
544 591
545 // Encode outbound data 592 // Encode outbound data
546 if (!string.IsNullOrEmpty(OutboundBody)) 593 if (!string.IsNullOrEmpty(OutboundBody))
@@ -552,12 +599,11 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
552 bstream.Write(data, 0, data.Length); 599 bstream.Write(data, 0, data.Length);
553 } 600 }
554 601
602 Request.Timeout = HttpTimeout;
555 try 603 try
556 { 604 {
557 IAsyncResult result = (IAsyncResult)Request.BeginGetResponse(ResponseCallback, null); 605 // execute the request
558 606 response = (HttpWebResponse) Request.GetResponse();
559 ThreadPool.RegisterWaitForSingleObject(
560 result.AsyncWaitHandle, new WaitOrTimerCallback(TimeoutCallback), null, HttpTimeout, true);
561 } 607 }
562 catch (WebException e) 608 catch (WebException e)
563 { 609 {
@@ -565,67 +611,74 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
565 { 611 {
566 throw; 612 throw;
567 } 613 }
614 response = (HttpWebResponse)e.Response;
615 }
568 616
569 HttpWebResponse response = (HttpWebResponse)e.Response; 617 Status = (int)response.StatusCode;
570 618
571 Status = (int)response.StatusCode; 619 resStream = response.GetResponseStream();
572 ResponseBody = response.StatusDescription; 620 int totalBodyBytes = 0;
573 _finished = true; 621 int maxBytes = HttpBodyMaxLen;
574 } 622 if(maxBytes > buf.Length)
575 } 623 maxBytes = buf.Length;
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 624
581 Status = (int)OSHttpStatusCode.ClientErrorJoker; 625 // we need to read all allowed or UFT8 conversion may fail
582 ResponseBody = e.Message; 626 do
583 _finished = true; 627 {
584 } 628 // fill the buffer with data
585 } 629 count = resStream.Read(buf, totalBodyBytes, maxBytes - totalBodyBytes);
630 totalBodyBytes += count;
631 if (totalBodyBytes >= maxBytes)
632 break;
586 633
587 private void ResponseCallback(IAsyncResult ar) 634 } while (count > 0); // any more data to read?
588 {
589 HttpWebResponse response = null;
590 635
591 try 636 if(totalBodyBytes > 0)
592 {
593 try
594 { 637 {
595 response = (HttpWebResponse)Request.EndGetResponse(ar); 638 tempString = Util.UTF8.GetString(buf, 0, totalBodyBytes);
639 ResponseBody = tempString.Replace("\r", "");
596 } 640 }
597 catch (WebException e) 641 else
642 ResponseBody = "";
643 }
644 catch (WebException e)
645 {
646 if (e.Status == WebExceptionStatus.ProtocolError)
598 { 647 {
599 if (e.Status != WebExceptionStatus.ProtocolError) 648 HttpWebResponse webRsp = (HttpWebResponse)((WebException)e).Response;
649 Status = (int)webRsp.StatusCode;
650 try
600 { 651 {
601 throw; 652 using (Stream responseStream = webRsp.GetResponseStream())
653 {
654 using (StreamReader reader = new StreamReader(responseStream))
655 ResponseBody = reader.ReadToEnd();
656 }
657 }
658 catch
659 {
660 ResponseBody = webRsp.StatusDescription;
602 } 661 }
603
604 response = (HttpWebResponse)e.Response;
605 } 662 }
606 663 else
607 Status = (int)response.StatusCode;
608
609 using (Stream stream = response.GetResponseStream())
610 { 664 {
611 StreamReader reader = new StreamReader(stream, Encoding.UTF8); 665 Status = (int)OSHttpStatusCode.ClientErrorJoker;
612 ResponseBody = reader.ReadToEnd(); 666 ResponseBody = e.Message;
613 } 667 }
614 } 668 }
615 catch (Exception e) 669 catch (Exception e)
616 { 670 {
617 Status = (int)OSHttpStatusCode.ClientErrorJoker; 671 // 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 } 672 }
623 finally 673 finally
624 { 674 {
675 if (resStream != null)
676 resStream.Close();
625 if (response != null) 677 if (response != null)
626 response.Close(); 678 response.Close();
627 679
628 // We need to resubmit 680
681 // We need to resubmit
629 if ( 682 if (
630 (Status == (int)HttpStatusCode.MovedPermanently 683 (Status == (int)HttpStatusCode.MovedPermanently
631 || Status == (int)HttpStatusCode.Found 684 || Status == (int)HttpStatusCode.Found
@@ -670,22 +723,24 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
670 else 723 else
671 { 724 {
672 _finished = true; 725 _finished = true;
726 if (ResponseBody == null)
727 ResponseBody = String.Empty;
673 } 728 }
674 } 729 }
675 } 730 }
676 731
677 private void TimeoutCallback(object state, bool timedOut)
678 {
679 if (timedOut)
680 Request.Abort();
681 }
682
683 public void Stop() 732 public void Stop()
684 { 733 {
685// m_log.DebugFormat("[SCRIPTS HTTP REQUESTS]: Stopping request to {0} for {1} ", Url, ItemID); 734 try
686 735 {
687 if (Request != null) 736 if (!WorkItem.Cancel())
688 Request.Abort(); 737 {
738 WorkItem.Cancel(true);
739 }
740 }
741 catch (Exception)
742 {
743 }
689 } 744 }
690 } 745 }
691} \ No newline at end of file 746}
diff --git a/OpenSim/Region/CoreModules/Scripting/HttpRequest/Tests/ScriptsHttpRequestsTests.cs b/OpenSim/Region/CoreModules/Scripting/HttpRequest/Tests/ScriptsHttpRequestsTests.cs
index d22487e..7e223d7 100644
--- a/OpenSim/Region/CoreModules/Scripting/HttpRequest/Tests/ScriptsHttpRequestsTests.cs
+++ b/OpenSim/Region/CoreModules/Scripting/HttpRequest/Tests/ScriptsHttpRequestsTests.cs
@@ -45,7 +45,7 @@ using OpenSim.Tests.Common;
45namespace OpenSim.Region.CoreModules.Scripting.HttpRequest.Tests 45namespace OpenSim.Region.CoreModules.Scripting.HttpRequest.Tests
46{ 46{
47 class TestWebRequestCreate : IWebRequestCreate 47 class TestWebRequestCreate : IWebRequestCreate
48 { 48 {
49 public TestWebRequest NextRequest { get; set; } 49 public TestWebRequest NextRequest { get; set; }
50 50
51 public WebRequest Create(Uri uri) 51 public WebRequest Create(Uri uri)
@@ -65,13 +65,13 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest.Tests
65 65
66 public Func<IAsyncResult, WebResponse> OnEndGetResponse { get; set; } 66 public Func<IAsyncResult, WebResponse> OnEndGetResponse { get; set; }
67 67
68 public TestWebRequest() : base() 68 public TestWebRequest() : base()
69 { 69 {
70// Console.WriteLine("created"); 70// Console.WriteLine("created");
71 } 71 }
72 72
73// public TestWebRequest(SerializationInfo serializationInfo, StreamingContext streamingContext) 73// public TestWebRequest(SerializationInfo serializationInfo, StreamingContext streamingContext)
74// : base(serializationInfo, streamingContext) 74// : base(serializationInfo, streamingContext)
75// { 75// {
76// Console.WriteLine("created"); 76// Console.WriteLine("created");
77// } 77// }
@@ -97,7 +97,7 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest.Tests
97 public string Response { get; set; } 97 public string Response { get; set; }
98 98
99#pragma warning disable 0618 99#pragma warning disable 0618
100 public TestHttpWebResponse(SerializationInfo serializationInfo, StreamingContext streamingContext) 100 public TestHttpWebResponse(SerializationInfo serializationInfo, StreamingContext streamingContext)
101 : base(serializationInfo, streamingContext) {} 101 : base(serializationInfo, streamingContext) {}
102#pragma warning restore 0618 102#pragma warning restore 0618
103 103
@@ -111,24 +111,24 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest.Tests
111 { 111 {
112 WaitHandle m_wh = new ManualResetEvent(true); 112 WaitHandle m_wh = new ManualResetEvent(true);
113 113
114 object IAsyncResult.AsyncState 114 object IAsyncResult.AsyncState
115 { 115 {
116 get { 116 get {
117 throw new System.NotImplementedException (); 117 throw new System.NotImplementedException ();
118 } 118 }
119 } 119 }
120 120
121 WaitHandle IAsyncResult.AsyncWaitHandle 121 WaitHandle IAsyncResult.AsyncWaitHandle
122 { 122 {
123 get { return m_wh; } 123 get { return m_wh; }
124 } 124 }
125 125
126 bool IAsyncResult.CompletedSynchronously 126 bool IAsyncResult.CompletedSynchronously
127 { 127 {
128 get { return false; } 128 get { return false; }
129 } 129 }
130 130
131 bool IAsyncResult.IsCompleted 131 bool IAsyncResult.IsCompleted
132 { 132 {
133 get { return true; } 133 get { return true; }
134 } 134 }
@@ -155,7 +155,7 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest.Tests
155 TestHelpers.EnableLogging(); 155 TestHelpers.EnableLogging();
156 156
157 if (!Util.IsPlatformMono) 157 if (!Util.IsPlatformMono)
158 Assert.Ignore("Ignoring test since can only currently run on Mono"); 158 Assert.Ignore("Ignoring test since can only currently run on Mono");
159 159
160 string rawResponse = "boom"; 160 string rawResponse = "boom";
161 161
@@ -163,7 +163,7 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest.Tests
163 163
164 TestWebRequest twr = new TestWebRequest(); 164 TestWebRequest twr = new TestWebRequest();
165 //twr.OnEndGetResponse += ar => new TestHttpWebResponse(null, new StreamingContext()); 165 //twr.OnEndGetResponse += ar => new TestHttpWebResponse(null, new StreamingContext());
166 twr.OnEndGetResponse += ar => 166 twr.OnEndGetResponse += ar =>
167 { 167 {
168 SerializationInfo si = new SerializationInfo(typeof(HttpWebResponse), new FormatterConverter()); 168 SerializationInfo si = new SerializationInfo(typeof(HttpWebResponse), new FormatterConverter());
169 StreamingContext sc = new StreamingContext(); 169 StreamingContext sc = new StreamingContext();
diff --git a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs
index 99a3122..11fc513 100644
--- a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs
@@ -26,10 +26,11 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Threading;
30using System.Collections.Generic; 29using System.Collections.Generic;
31using System.Collections; 30using System.Collections;
32using System.Reflection; 31using System.Reflection;
32using System.Net;
33using System.Net.Sockets;
33using log4net; 34using log4net;
34using Mono.Addins; 35using Mono.Addins;
35using Nini.Config; 36using Nini.Config;
@@ -42,40 +43,17 @@ using OpenSim.Region.Framework.Scenes;
42 43
43namespace OpenSim.Region.CoreModules.Scripting.LSLHttp 44namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
44{ 45{
45 /// <summary>
46 /// Data describing an external URL set up by a script.
47 /// </summary>
48 public class UrlData 46 public class UrlData
49 { 47 {
50 /// <summary>
51 /// Scene object part hosting the script
52 /// </summary>
53 public UUID hostID; 48 public UUID hostID;
54
55 /// <summary>
56 /// The item ID of the script that requested the URL.
57 /// </summary>
58 public UUID itemID; 49 public UUID itemID;
59
60 /// <summary>
61 /// The script engine that runs the script.
62 /// </summary>
63 public IScriptModule engine; 50 public IScriptModule engine;
64
65 /// <summary>
66 /// The generated URL.
67 /// </summary>
68 public string url; 51 public string url;
69
70 /// <summary>
71 /// The random UUID component of the generated URL.
72 /// </summary>
73 public UUID urlcode; 52 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; 53 public Dictionary<UUID, RequestData> requests;
54 public bool isSsl;
55 public Scene scene;
56 public bool allowXss;
79 } 57 }
80 58
81 public class RequestData 59 public class RequestData
@@ -89,7 +67,11 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
89 //public ManualResetEvent ev; 67 //public ManualResetEvent ev;
90 public bool requestDone; 68 public bool requestDone;
91 public int startTime; 69 public int startTime;
70 public bool responseSent;
92 public string uri; 71 public string uri;
72 public bool allowResponseType = false;
73 public UUID hostID;
74 public Scene scene;
93 } 75 }
94 76
95 /// <summary> 77 /// <summary>
@@ -102,40 +84,33 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
102 LogManager.GetLogger( 84 LogManager.GetLogger(
103 MethodBase.GetCurrentMethod().DeclaringType); 85 MethodBase.GetCurrentMethod().DeclaringType);
104 86
105 /// <summary> 87 protected Dictionary<UUID, UrlData> m_RequestMap =
106 /// Indexs the URL request metadata (which script requested it, outstanding requests, etc.) by the request ID 88 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 89
115 /// <summary> 90 protected Dictionary<string, UrlData> m_UrlMap =
116 /// Indexs the URL request metadata (which script requested it, outstanding requests, etc.) by the full URL 91 new Dictionary<string, UrlData>();
117 /// </summary>
118 private Dictionary<string, UrlData> m_UrlMap = new Dictionary<string, UrlData>();
119 92
120 private uint m_HttpsPort = 0; 93 protected bool m_enabled = false;
121 private IHttpServer m_HttpServer = null; 94 protected string m_ErrorStr;
122 private IHttpServer m_HttpsServer = null; 95 protected uint m_HttpsPort = 0;
96 protected IHttpServer m_HttpServer = null;
97 protected IHttpServer m_HttpsServer = null;
123 98
124 public string ExternalHostNameForLSL { get; private set; } 99 public string ExternalHostNameForLSL { get; protected set; }
125 100
126 /// <summary> 101 /// <summary>
127 /// The default maximum number of urls 102 /// The default maximum number of urls
128 /// </summary> 103 /// </summary>
129 public const int DefaultTotalUrls = 100; 104 public const int DefaultTotalUrls = 15000;
130 105
131 /// <summary> 106 /// <summary>
132 /// Maximum number of external urls that can be set up by this module. 107 /// Maximum number of external urls that can be set up by this module.
133 /// </summary> 108 /// </summary>
134 public int TotalUrls { get; set; } 109 public int TotalUrls { get; set; }
135 110
136 public Type ReplaceableInterface 111 public Type ReplaceableInterface
137 { 112 {
138 get { return null; } 113 get { return typeof(IUrlModule); }
139 } 114 }
140 115
141 public string Name 116 public string Name
@@ -146,6 +121,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
146 public void Initialise(IConfigSource config) 121 public void Initialise(IConfigSource config)
147 { 122 {
148 IConfig networkConfig = config.Configs["Network"]; 123 IConfig networkConfig = config.Configs["Network"];
124 m_enabled = false;
149 125
150 if (networkConfig != null) 126 if (networkConfig != null)
151 { 127 {
@@ -156,9 +132,31 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
156 if (ssl_enabled) 132 if (ssl_enabled)
157 m_HttpsPort = (uint)config.Configs["Network"].GetInt("https_port", (int)m_HttpsPort); 133 m_HttpsPort = (uint)config.Configs["Network"].GetInt("https_port", (int)m_HttpsPort);
158 } 134 }
135 else
136 {
137 m_ErrorStr = "[Network] configuration missing, HTTP listener for LSL disabled";
138 m_log.Warn("[URL MODULE]: " + m_ErrorStr);
139 return;
140 }
159 141
160 if (ExternalHostNameForLSL == null) 142 if (String.IsNullOrWhiteSpace(ExternalHostNameForLSL))
161 ExternalHostNameForLSL = System.Environment.MachineName; 143 {
144 m_ErrorStr = "ExternalHostNameForLSL not defined in configuration, HTTP listener for LSL disabled";
145 m_log.Warn("[URL MODULE]: " + m_ErrorStr);
146 return;
147 }
148
149 IPAddress ia = null;
150 ia = Util.GetHostFromDNS(ExternalHostNameForLSL);
151 if (ia == null)
152 {
153 m_ErrorStr = "Could not resolve ExternalHostNameForLSL, HTTP listener for LSL disabled";
154 m_log.Warn("[URL MODULE]: " + m_ErrorStr);
155 return;
156 }
157
158 m_enabled = true;
159 m_ErrorStr = String.Empty;
162 160
163 IConfig llFunctionsConfig = config.Configs["LL-Functions"]; 161 IConfig llFunctionsConfig = config.Configs["LL-Functions"];
164 162
@@ -174,7 +172,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
174 172
175 public void AddRegion(Scene scene) 173 public void AddRegion(Scene scene)
176 { 174 {
177 if (m_HttpServer == null) 175 if (m_enabled && m_HttpServer == null)
178 { 176 {
179 // There can only be one 177 // There can only be one
180 // 178 //
@@ -204,21 +202,39 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
204 202
205 public void RemoveRegion(Scene scene) 203 public void RemoveRegion(Scene scene)
206 { 204 {
205 // Drop references to that scene
206 foreach (KeyValuePair<string, UrlData> kvp in m_UrlMap)
207 {
208 if (kvp.Value.scene == scene)
209 kvp.Value.scene = null;
210 }
211 foreach (KeyValuePair<UUID, UrlData> kvp in m_RequestMap)
212 {
213 if (kvp.Value.scene == scene)
214 kvp.Value.scene = null;
215 }
207 } 216 }
208 217
209 public void Close() 218 public void Close()
210 { 219 {
211 } 220 }
212 221
213 public UUID RequestURL(IScriptModule engine, SceneObjectPart host, UUID itemID) 222 public UUID RequestURL(IScriptModule engine, SceneObjectPart host, UUID itemID, Hashtable options)
214 { 223 {
215 UUID urlcode = UUID.Random(); 224 UUID urlcode = UUID.Random();
216 225
226 if(!m_enabled)
227 {
228 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_DENIED", m_ErrorStr });
229 return urlcode;
230 }
231
217 lock (m_UrlMap) 232 lock (m_UrlMap)
218 { 233 {
219 if (m_UrlMap.Count >= TotalUrls) 234 if (m_UrlMap.Count >= TotalUrls)
220 { 235 {
221 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_DENIED", "" }); 236 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_DENIED",
237 "Too many URLs already open" });
222 return urlcode; 238 return urlcode;
223 } 239 }
224 string url = "http://" + ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + "/lslhttp/" + urlcode.ToString() + "/"; 240 string url = "http://" + ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + "/lslhttp/" + urlcode.ToString() + "/";
@@ -229,20 +245,26 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
229 urlData.engine = engine; 245 urlData.engine = engine;
230 urlData.url = url; 246 urlData.url = url;
231 urlData.urlcode = urlcode; 247 urlData.urlcode = urlcode;
248 urlData.isSsl = false;
232 urlData.requests = new Dictionary<UUID, RequestData>(); 249 urlData.requests = new Dictionary<UUID, RequestData>();
233 250 urlData.scene = host.ParentGroup.Scene;
251 urlData.allowXss = false;
252
253 if (options != null && options["allowXss"] != null)
254 urlData.allowXss = true;
255
234 m_UrlMap[url] = urlData; 256 m_UrlMap[url] = urlData;
235 257
236 string uri = "/lslhttp/" + urlcode.ToString() + "/"; 258 string uri = "/lslhttp/" + urlcode.ToString() + "/";
237 259
238 PollServiceEventArgs args 260 PollServiceEventArgs args
239 = new PollServiceEventArgs(HttpRequestHandler, uri, HasEvents, GetEvents, NoEvents, urlcode, 25000); 261 = new PollServiceEventArgs(HttpRequestHandler, uri, HasEvents, GetEvents, NoEvents, urlcode, 25000);
240 args.Type = PollServiceEventArgs.EventType.LslHttp; 262 args.Type = PollServiceEventArgs.EventType.LslHttp;
241 m_HttpServer.AddPollServiceHTTPHandler(uri, args); 263 m_HttpServer.AddPollServiceHTTPHandler(uri, args);
242 264
243 m_log.DebugFormat( 265// m_log.DebugFormat(
244 "[URL MODULE]: Set up incoming request url {0} for {1} in {2} {3}", 266// "[URL MODULE]: Set up incoming request url {0} for {1} in {2} {3}",
245 uri, itemID, host.Name, host.LocalId); 267// uri, itemID, host.Name, host.LocalId);
246 268
247 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_GRANTED", url }); 269 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_GRANTED", url });
248 } 270 }
@@ -250,10 +272,16 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
250 return urlcode; 272 return urlcode;
251 } 273 }
252 274
253 public UUID RequestSecureURL(IScriptModule engine, SceneObjectPart host, UUID itemID) 275 public UUID RequestSecureURL(IScriptModule engine, SceneObjectPart host, UUID itemID, Hashtable options)
254 { 276 {
255 UUID urlcode = UUID.Random(); 277 UUID urlcode = UUID.Random();
256 278
279 if(!m_enabled)
280 {
281 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_DENIED", m_ErrorStr });
282 return urlcode;
283 }
284
257 if (m_HttpsServer == null) 285 if (m_HttpsServer == null)
258 { 286 {
259 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_DENIED", "" }); 287 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_DENIED", "" });
@@ -264,7 +292,8 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
264 { 292 {
265 if (m_UrlMap.Count >= TotalUrls) 293 if (m_UrlMap.Count >= TotalUrls)
266 { 294 {
267 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_DENIED", "" }); 295 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_DENIED",
296 "Too many URLs already open" });
268 return urlcode; 297 return urlcode;
269 } 298 }
270 string url = "https://" + ExternalHostNameForLSL + ":" + m_HttpsServer.Port.ToString() + "/lslhttps/" + urlcode.ToString() + "/"; 299 string url = "https://" + ExternalHostNameForLSL + ":" + m_HttpsServer.Port.ToString() + "/lslhttps/" + urlcode.ToString() + "/";
@@ -275,20 +304,25 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
275 urlData.engine = engine; 304 urlData.engine = engine;
276 urlData.url = url; 305 urlData.url = url;
277 urlData.urlcode = urlcode; 306 urlData.urlcode = urlcode;
307 urlData.isSsl = true;
278 urlData.requests = new Dictionary<UUID, RequestData>(); 308 urlData.requests = new Dictionary<UUID, RequestData>();
309 urlData.allowXss = false;
310
311 if (options != null && options["allowXss"] != null)
312 urlData.allowXss = true;
279 313
280 m_UrlMap[url] = urlData; 314 m_UrlMap[url] = urlData;
281 315
282 string uri = "/lslhttps/" + urlcode.ToString() + "/"; 316 string uri = "/lslhttps/" + urlcode.ToString() + "/";
283 317
284 PollServiceEventArgs args 318 PollServiceEventArgs args
285 = new PollServiceEventArgs(HttpRequestHandler, uri, HasEvents, GetEvents, NoEvents, urlcode, 25000); 319 = new PollServiceEventArgs(HttpRequestHandler, uri, HasEvents, GetEvents, NoEvents, urlcode, 25000);
286 args.Type = PollServiceEventArgs.EventType.LslHttp; 320 args.Type = PollServiceEventArgs.EventType.LslHttp;
287 m_HttpsServer.AddPollServiceHTTPHandler(uri, args); 321 m_HttpsServer.AddPollServiceHTTPHandler(uri, args);
288 322
289 m_log.DebugFormat( 323// m_log.DebugFormat(
290 "[URL MODULE]: Set up incoming secure request url {0} for {1} in {2} {3}", 324// "[URL MODULE]: Set up incoming secure request url {0} for {1} in {2} {3}",
291 uri, itemID, host.Name, host.LocalId); 325// uri, itemID, host.Name, host.LocalId);
292 326
293 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_GRANTED", url }); 327 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_GRANTED", url });
294 } 328 }
@@ -307,18 +341,21 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
307 return; 341 return;
308 } 342 }
309 343
310 foreach (UUID req in data.requests.Keys) 344 lock (m_RequestMap)
311 m_RequestMap.Remove(req); 345 {
346 foreach (UUID req in data.requests.Keys)
347 m_RequestMap.Remove(req);
348 }
312 349
313 m_log.DebugFormat( 350// m_log.DebugFormat(
314 "[URL MODULE]: Releasing url {0} for {1} in {2}", 351// "[URL MODULE]: Releasing url {0} for {1} in {2}",
315 url, data.itemID, data.hostID); 352// url, data.itemID, data.hostID);
316 353
317 RemoveUrl(data); 354 RemoveUrl(data);
318 m_UrlMap.Remove(url); 355 m_UrlMap.Remove(url);
319 } 356 }
320 } 357 }
321 358
322 public void HttpContentType(UUID request, string type) 359 public void HttpContentType(UUID request, string type)
323 { 360 {
324 lock (m_UrlMap) 361 lock (m_UrlMap)
@@ -334,32 +371,42 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
334 } 371 }
335 } 372 }
336 } 373 }
337 374
338 public void HttpResponse(UUID request, int status, string body) 375 public void HttpResponse(UUID request, int status, string body)
339 { 376 {
340 lock (m_UrlMap) 377 lock (m_RequestMap)
341 { 378 {
342 if (m_RequestMap.ContainsKey(request)) 379 if (m_RequestMap.ContainsKey(request))
343 { 380 {
344 UrlData urlData = m_RequestMap[request]; 381 UrlData urlData = m_RequestMap[request];
345 string responseBody = body; 382 if (!urlData.requests[request].responseSent)
346 if (urlData.requests[request].responseType.Equals("text/plain"))
347 { 383 {
348 string value; 384 string responseBody = body;
349 if (urlData.requests[request].headers.TryGetValue("user-agent", out value)) 385
386 // If we have no OpenID from built-in browser, disable this
387 if (!urlData.requests[request].allowResponseType)
388 urlData.requests[request].responseType = "text/plain";
389
390 if (urlData.requests[request].responseType.Equals("text/plain"))
350 { 391 {
351 if (value != null && value.IndexOf("MSIE") >= 0) 392 string value;
393 if (urlData.requests[request].headers.TryGetValue("user-agent", out value))
352 { 394 {
353 // wrap the html escaped response if the target client is IE 395 if (value != null && value.IndexOf("MSIE") >= 0)
354 // It ignores "text/plain" if the body is html 396 {
355 responseBody = "<html>" + System.Web.HttpUtility.HtmlEncode(body) + "</html>"; 397 // wrap the html escaped response if the target client is IE
398 // It ignores "text/plain" if the body is html
399 responseBody = "<html>" + System.Web.HttpUtility.HtmlEncode(body) + "</html>";
400 }
356 } 401 }
357 } 402 }
403
404 urlData.requests[request].responseCode = status;
405 urlData.requests[request].responseBody = responseBody;
406 //urlData.requests[request].ev.Set();
407 urlData.requests[request].requestDone = true;
408 urlData.requests[request].responseSent = true;
358 } 409 }
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 } 410 }
364 else 411 else
365 { 412 {
@@ -370,7 +417,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
370 417
371 public string GetHttpHeader(UUID requestId, string header) 418 public string GetHttpHeader(UUID requestId, string header)
372 { 419 {
373 lock (m_UrlMap) 420 lock (m_RequestMap)
374 { 421 {
375 if (m_RequestMap.ContainsKey(requestId)) 422 if (m_RequestMap.ContainsKey(requestId))
376 { 423 {
@@ -384,7 +431,6 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
384 m_log.Warn("[HttpRequestHandler] There was no http-in request with id " + requestId); 431 m_log.Warn("[HttpRequestHandler] There was no http-in request with id " + requestId);
385 } 432 }
386 } 433 }
387
388 return String.Empty; 434 return String.Empty;
389 } 435 }
390 436
@@ -397,7 +443,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
397 public void ScriptRemoved(UUID itemID) 443 public void ScriptRemoved(UUID itemID)
398 { 444 {
399// m_log.DebugFormat("[URL MODULE]: Removing script {0}", itemID); 445// m_log.DebugFormat("[URL MODULE]: Removing script {0}", itemID);
400 446
401 lock (m_UrlMap) 447 lock (m_UrlMap)
402 { 448 {
403 List<string> removeURLs = new List<string>(); 449 List<string> removeURLs = new List<string>();
@@ -408,8 +454,11 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
408 { 454 {
409 RemoveUrl(url.Value); 455 RemoveUrl(url.Value);
410 removeURLs.Add(url.Key); 456 removeURLs.Add(url.Key);
411 foreach (UUID req in url.Value.requests.Keys) 457 lock (m_RequestMap)
412 m_RequestMap.Remove(req); 458 {
459 foreach (UUID req in url.Value.requests.Keys)
460 m_RequestMap.Remove(req);
461 }
413 } 462 }
414 } 463 }
415 464
@@ -430,9 +479,11 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
430 { 479 {
431 RemoveUrl(url.Value); 480 RemoveUrl(url.Value);
432 removeURLs.Add(url.Key); 481 removeURLs.Add(url.Key);
433 482 lock (m_RequestMap)
434 foreach (UUID req in url.Value.requests.Keys) 483 {
435 m_RequestMap.Remove(req); 484 foreach (UUID req in url.Value.requests.Keys)
485 m_RequestMap.Remove(req);
486 }
436 } 487 }
437 } 488 }
438 489
@@ -441,123 +492,131 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
441 } 492 }
442 } 493 }
443 494
444 private void RemoveUrl(UrlData data) 495
496 protected void RemoveUrl(UrlData data)
445 { 497 {
446 m_HttpServer.RemoveHTTPHandler("", "/lslhttp/" + data.urlcode.ToString() + "/"); 498 if (data.isSsl)
499 m_HttpsServer.RemoveHTTPHandler("", "/lslhttps/"+data.urlcode.ToString()+"/");
500 else
501 m_HttpServer.RemoveHTTPHandler("", "/lslhttp/"+data.urlcode.ToString()+"/");
447 } 502 }
448 503
449 private Hashtable NoEvents(UUID requestID, UUID sessionID) 504 protected Hashtable NoEvents(UUID requestID, UUID sessionID)
450 { 505 {
451 Hashtable response = new Hashtable(); 506 Hashtable response = new Hashtable();
452 UrlData urlData; 507 UrlData url;
453 508 int startTime = 0;
454 lock (m_UrlMap) 509 lock (m_RequestMap)
455 { 510 {
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)) 511 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; 512 return response;
467 } 513 url = m_RequestMap[requestID];
514 startTime = url.requests[requestID].startTime;
515 }
468 516
469 urlData = m_RequestMap[requestID]; 517 if (System.Environment.TickCount - startTime > 25000)
518 {
519 response["int_response_code"] = 500;
520 response["str_response_string"] = "Script timeout";
521 response["content_type"] = "text/plain";
522 response["keepalive"] = false;
523 response["reusecontext"] = false;
470 524
471 if (System.Environment.TickCount - urlData.requests[requestID].startTime > 25000) 525 //remove from map
526 lock (url.requests)
527 {
528 url.requests.Remove(requestID);
529 }
530 lock (m_RequestMap)
472 { 531 {
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); 532 m_RequestMap.Remove(requestID);
482
483 return response;
484 } 533 }
534
535 return response;
485 } 536 }
486 537
538
487 return response; 539 return response;
488 } 540 }
489 541
490 private bool HasEvents(UUID requestID, UUID sessionID) 542 protected bool HasEvents(UUID requestID, UUID sessionID)
491 { 543 {
492 lock (m_UrlMap) 544 UrlData url=null;
545
546 lock (m_RequestMap)
493 { 547 {
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)) 548 if (!m_RequestMap.ContainsKey(requestID))
500 { 549 {
501 return true; 550 return false;
502 } 551 }
503 552 url = m_RequestMap[requestID];
504 UrlData urlData = m_RequestMap[requestID]; 553 }
505 554 lock (url.requests)
506 if (!urlData.requests.ContainsKey(requestID)) 555 {
556 if (!url.requests.ContainsKey(requestID))
507 { 557 {
508 return true; 558 return false;
509 } 559 }
510 560 else
511 // Trigger return of timeout response.
512 if (System.Environment.TickCount - urlData.requests[requestID].startTime > 25000)
513 { 561 {
514 return true; 562 if (System.Environment.TickCount - url.requests[requestID].startTime > 25000)
563 {
564 return true;
565 }
566 if (url.requests[requestID].requestDone)
567 return true;
568 else
569 return false;
515 } 570 }
516
517 return urlData.requests[requestID].requestDone;
518 } 571 }
519 } 572 }
520 573 protected Hashtable GetEvents(UUID requestID, UUID sessionID)
521 private Hashtable GetEvents(UUID requestID, UUID sessionID)
522 { 574 {
523 Hashtable response; 575 UrlData url = null;
576 RequestData requestData = null;
524 577
525 lock (m_UrlMap) 578 lock (m_RequestMap)
526 { 579 {
527 UrlData url = null;
528 RequestData requestData = null;
529
530 if (!m_RequestMap.ContainsKey(requestID)) 580 if (!m_RequestMap.ContainsKey(requestID))
531 return NoEvents(requestID, sessionID); 581 return NoEvents(requestID,sessionID);
532
533 url = m_RequestMap[requestID]; 582 url = m_RequestMap[requestID];
583 }
584 lock (url.requests)
585 {
534 requestData = url.requests[requestID]; 586 requestData = url.requests[requestID];
587 }
535 588
536 if (!requestData.requestDone) 589 if (!requestData.requestDone)
537 return NoEvents(requestID, sessionID); 590 return NoEvents(requestID,sessionID);
538
539 response = new Hashtable();
540 591
541 if (System.Environment.TickCount - requestData.startTime > 25000) 592 Hashtable response = new Hashtable();
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 593
551 //put response 594 if (System.Environment.TickCount - requestData.startTime > 25000)
552 response["int_response_code"] = requestData.responseCode; 595 {
553 response["str_response_string"] = requestData.responseBody; 596 response["int_response_code"] = 500;
554 response["content_type"] = requestData.responseType; 597 response["str_response_string"] = "Script timeout";
555 // response["content_type"] = "text/plain"; 598 response["content_type"] = "text/plain";
556 response["keepalive"] = false; 599 response["keepalive"] = false;
557 response["reusecontext"] = false; 600 response["reusecontext"] = false;
558 601 return response;
559 //remove from map 602 }
603 //put response
604 response["int_response_code"] = requestData.responseCode;
605 response["str_response_string"] = requestData.responseBody;
606 response["content_type"] = requestData.responseType;
607 response["keepalive"] = false;
608 response["reusecontext"] = false;
609
610 if (url.allowXss)
611 response["access_control_allow_origin"] = "*";
612
613 //remove from map
614 lock (url.requests)
615 {
560 url.requests.Remove(requestID); 616 url.requests.Remove(requestID);
617 }
618 lock (m_RequestMap)
619 {
561 m_RequestMap.Remove(requestID); 620 m_RequestMap.Remove(requestID);
562 } 621 }
563 622
@@ -566,44 +625,49 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
566 625
567 public void HttpRequestHandler(UUID requestID, Hashtable request) 626 public void HttpRequestHandler(UUID requestID, Hashtable request)
568 { 627 {
569 string uri = request["uri"].ToString(); 628 lock (request)
570 bool is_ssl = uri.Contains("lslhttps");
571
572 try
573 { 629 {
574 Hashtable headers = (Hashtable)request["headers"]; 630 string uri = request["uri"].ToString();
631 bool is_ssl = uri.Contains("lslhttps");
575 632
576// string uri_full = "http://" + m_ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + uri;// "/lslhttp/" + urlcode.ToString() + "/"; 633 try
634 {
635 Hashtable headers = (Hashtable)request["headers"];
577 636
578 int pos1 = uri.IndexOf("/");// /lslhttp 637// 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 638
587 pathInfo = uri.Substring(pos3); 639 int pos1 = uri.IndexOf("/");// /lslhttp
640 int pos2 = uri.IndexOf("/", pos1 + 1);// /lslhttp/
641 int pos3 = uri.IndexOf("/", pos2 + 1); // /lslhttp/urlcode
588 642
589 UrlData urlData = null; 643 string uri_tmp = uri.Substring(0, pos3 + 1);
644 //HTTP server code doesn't provide us with QueryStrings
645 string pathInfo;
646 string queryString;
647 queryString = "";
590 648
591 lock (m_UrlMap) 649 pathInfo = uri.Substring(pos3);
592 {
593 string url;
594 650
595 if (is_ssl) 651 UrlData url = null;
596 url = "https://" + ExternalHostNameForLSL + ":" + m_HttpsServer.Port.ToString() + uri_tmp; 652 string urlkey;
653 if (!is_ssl)
654 urlkey = "http://" + ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + uri_tmp;
655 //m_UrlMap[];
597 else 656 else
598 url = "http://" + ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + uri_tmp; 657 urlkey = "https://" + ExternalHostNameForLSL + ":" + m_HttpsServer.Port.ToString() + uri_tmp;
599 658
600 // Avoid a race - the request URL may have been released via llRequestUrl() whilst this 659 if (m_UrlMap.ContainsKey(urlkey))
601 // request was being processed. 660 {
602 if (!m_UrlMap.TryGetValue(url, out urlData)) 661 url = m_UrlMap[urlkey];
662 }
663 else
664 {
665 //m_log.Warn("[HttpRequestHandler]: http-in request failed; no such url: "+urlkey.ToString());
603 return; 666 return;
667 }
604 668
605 //for llGetHttpHeader support we need to store original URI here 669 //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 670 //to make x-path-info / x-query-string / x-script-url / x-remote-ip headers
607 //as per http://wiki.secondlife.com/wiki/LlGetHTTPHeader 671 //as per http://wiki.secondlife.com/wiki/LlGetHTTPHeader
608 672
609 RequestData requestData = new RequestData(); 673 RequestData requestData = new RequestData();
@@ -611,6 +675,8 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
611 requestData.requestDone = false; 675 requestData.requestDone = false;
612 requestData.startTime = System.Environment.TickCount; 676 requestData.startTime = System.Environment.TickCount;
613 requestData.uri = uri; 677 requestData.uri = uri;
678 requestData.hostID = url.hostID;
679 requestData.scene = url.scene;
614 if (requestData.headers == null) 680 if (requestData.headers == null)
615 requestData.headers = new Dictionary<string, string>(); 681 requestData.headers = new Dictionary<string, string>();
616 682
@@ -619,8 +685,33 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
619 string key = (string)header.Key; 685 string key = (string)header.Key;
620 string value = (string)header.Value; 686 string value = (string)header.Value;
621 requestData.headers.Add(key, value); 687 requestData.headers.Add(key, value);
688 if (key == "cookie")
689 {
690 string[] parts = value.Split(new char[] {'='});
691 if (parts[0] == "agni_sl_session_id" && parts.Length > 1)
692 {
693 string cookie = Uri.UnescapeDataString(parts[1]);
694 string[] crumbs = cookie.Split(new char[] {':'});
695 UUID owner;
696 if (crumbs.Length == 2 && UUID.TryParse(crumbs[0], out owner))
697 {
698 if (crumbs[1].Length == 32)
699 {
700 Scene scene = requestData.scene;
701 if (scene != null)
702 {
703 SceneObjectPart host = scene.GetSceneObjectPart(requestData.hostID);
704 if (host != null)
705 {
706 if (host.OwnerID == owner)
707 requestData.allowResponseType = true;
708 }
709 }
710 }
711 }
712 }
713 }
622 } 714 }
623
624 foreach (DictionaryEntry de in request) 715 foreach (DictionaryEntry de in request)
625 { 716 {
626 if (de.Key.ToString() == "querystringkeys") 717 if (de.Key.ToString() == "querystringkeys")
@@ -631,13 +722,21 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
631 if (request.ContainsKey(key)) 722 if (request.ContainsKey(key))
632 { 723 {
633 string val = (String)request[key]; 724 string val = (String)request[key];
634 queryString = queryString + key + "=" + val + "&"; 725 if (key != "")
726 {
727 queryString = queryString + key + "=" + val + "&";
728 }
729 else
730 {
731 queryString = queryString + val + "&";
732 }
635 } 733 }
636 } 734 }
637
638 if (queryString.Length > 1) 735 if (queryString.Length > 1)
639 queryString = queryString.Substring(0, queryString.Length - 1); 736 queryString = queryString.Substring(0, queryString.Length - 1);
737
640 } 738 }
739
641 } 740 }
642 741
643 //if this machine is behind DNAT/port forwarding, currently this is being 742 //if this machine is behind DNAT/port forwarding, currently this is being
@@ -645,27 +744,38 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
645 requestData.headers["x-remote-ip"] = requestData.headers["remote_addr"]; 744 requestData.headers["x-remote-ip"] = requestData.headers["remote_addr"];
646 requestData.headers["x-path-info"] = pathInfo; 745 requestData.headers["x-path-info"] = pathInfo;
647 requestData.headers["x-query-string"] = queryString; 746 requestData.headers["x-query-string"] = queryString;
648 requestData.headers["x-script-url"] = urlData.url; 747 requestData.headers["x-script-url"] = url.url;
649 748
650 urlData.requests.Add(requestID, requestData); 749 //requestData.ev = new ManualResetEvent(false);
651 m_RequestMap.Add(requestID, urlData); 750 lock (url.requests)
652 } 751 {
752 url.requests.Add(requestID, requestData);
753 }
754 lock (m_RequestMap)
755 {
756 //add to request map
757 m_RequestMap.Add(requestID, url);
758 }
653 759
654 urlData.engine.PostScriptEvent( 760 url.engine.PostScriptEvent(url.itemID, "http_request", new Object[] { requestID.ToString(), request["http-method"].ToString(), request["body"].ToString() });
655 urlData.itemID, 761
656 "http_request", 762 //send initial response?
657 new Object[] { requestID.ToString(), request["http-method"].ToString(), request["body"].ToString() }); 763// Hashtable response = new Hashtable();
658 } 764
659 catch (Exception we) 765 return;
660 { 766
661 //Hashtable response = new Hashtable(); 767 }
662 m_log.Warn("[HttpRequestHandler]: http-in request failed"); 768 catch (Exception we)
663 m_log.Warn(we.Message); 769 {
664 m_log.Warn(we.StackTrace); 770 //Hashtable response = new Hashtable();
771 m_log.Warn("[HttpRequestHandler]: http-in request failed");
772 m_log.Warn(we.Message);
773 m_log.Warn(we.StackTrace);
774 }
665 } 775 }
666 } 776 }
667 777
668 private void OnScriptReset(uint localID, UUID itemID) 778 protected void OnScriptReset(uint localID, UUID itemID)
669 { 779 {
670 ScriptRemoved(itemID); 780 ScriptRemoved(itemID);
671 } 781 }
diff --git a/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs b/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs
index d45962f..673a453 100644
--- a/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs
@@ -98,7 +98,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL
98 return false; 98 return false;
99 } 99 }
100 100
101 public void GetDrawStringSize(string text, string fontName, int fontSize, 101 public void GetDrawStringSize(string text, string fontName, int fontSize,
102 out double xSize, out double ySize) 102 out double xSize, out double ySize)
103 { 103 {
104 xSize = 0; 104 xSize = 0;
@@ -124,7 +124,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL
124 { 124 {
125 if (m_scene == null) 125 if (m_scene == null)
126 m_scene = scene; 126 m_scene = scene;
127 127
128 } 128 }
129 129
130 public void RemoveRegion(Scene scene) 130 public void RemoveRegion(Scene scene)
@@ -166,15 +166,15 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL
166 166
167 HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); 167 HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
168 request.AllowAutoRedirect = false; 168 request.AllowAutoRedirect = false;
169 169
170 if (!string.IsNullOrEmpty(m_proxyurl)) 170 if (!string.IsNullOrEmpty(m_proxyurl))
171 { 171 {
172 if (!string.IsNullOrEmpty(m_proxyexcepts)) 172 if (!string.IsNullOrEmpty(m_proxyexcepts))
173 { 173 {
174 string[] elist = m_proxyexcepts.Split(';'); 174 string[] elist = m_proxyexcepts.Split(';');
175 request.Proxy = new WebProxy(m_proxyurl, true, elist); 175 request.Proxy = new WebProxy(m_proxyurl, true, elist);
176 } 176 }
177 else 177 else
178 { 178 {
179 request.Proxy = new WebProxy(m_proxyurl, true); 179 request.Proxy = new WebProxy(m_proxyurl, true);
180 } 180 }
@@ -253,7 +253,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL
253 { 253 {
254 imageJ2000 = OpenJPEG.EncodeFromImage(resize, true); 254 imageJ2000 = OpenJPEG.EncodeFromImage(resize, true);
255 } 255 }
256 } 256 }
257 catch (Exception) 257 catch (Exception)
258 { 258 {
259 m_log.Error("[LOADIMAGEURLMODULE]: OpenJpeg Conversion Failed. Empty byte data returned!"); 259 m_log.Error("[LOADIMAGEURLMODULE]: OpenJpeg Conversion Failed. Empty byte data returned!");
@@ -268,33 +268,37 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL
268 catch (WebException) 268 catch (WebException)
269 { 269 {
270 } 270 }
271 catch (Exception e)
272 {
273 m_log.ErrorFormat("[LOADIMAGEURLMODULE]: unexpected exception {0}", e.Message);
274 }
271 finally 275 finally
272 { 276 {
273 if (stream != null) 277 if (stream != null)
274 stream.Close(); 278 stream.Close();
275 279
276 if (response != null) 280 if (response != null)
277 response.Close();
278
279 if (
280 response.StatusCode == HttpStatusCode.MovedPermanently
281 || response.StatusCode == HttpStatusCode.Found
282 || response.StatusCode == HttpStatusCode.SeeOther
283 || response.StatusCode == HttpStatusCode.TemporaryRedirect)
284 { 281 {
285 string redirectedUrl = response.Headers["Location"]; 282 if (response.StatusCode == HttpStatusCode.MovedPermanently
283 || response.StatusCode == HttpStatusCode.Found
284 || response.StatusCode == HttpStatusCode.SeeOther
285 || response.StatusCode == HttpStatusCode.TemporaryRedirect)
286 {
287 string redirectedUrl = response.Headers["Location"];
286 288
287 MakeHttpRequest(redirectedUrl, state.RequestID); 289 MakeHttpRequest(redirectedUrl, state.RequestID);
288 } 290 }
289 else 291 else
290 { 292 {
291 m_log.DebugFormat("[LOADIMAGEURLMODULE]: Returning {0} bytes of image data for request {1}", 293 m_log.DebugFormat("[LOADIMAGEURLMODULE]: Returning {0} bytes of image data for request {1}",
292 imageJ2000.Length, state.RequestID); 294 imageJ2000.Length, state.RequestID);
293 295
294 m_textureManager.ReturnData( 296 m_textureManager.ReturnData(
295 state.RequestID, 297 state.RequestID,
296 new OpenSim.Region.CoreModules.Scripting.DynamicTexture.DynamicTexture( 298 new OpenSim.Region.CoreModules.Scripting.DynamicTexture.DynamicTexture(
297 request.RequestUri, null, imageJ2000, newSize, false)); 299 request.RequestUri, null, imageJ2000, newSize, false));
300 }
301 response.Close();
298 } 302 }
299 } 303 }
300 } 304 }
diff --git a/OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs b/OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs
index 6da2222..9c3f08e 100644
--- a/OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs
@@ -89,7 +89,7 @@ namespace OpenSim.Region.CoreModules.Scripting.ScriptModuleComms
89 public void RegionLoaded(Scene scene) 89 public void RegionLoaded(Scene scene)
90 { 90 {
91 m_scriptModule = scene.RequestModuleInterface<IScriptModule>(); 91 m_scriptModule = scene.RequestModuleInterface<IScriptModule>();
92 92
93 if (m_scriptModule != null) 93 if (m_scriptModule != null)
94 m_log.Info("[MODULE COMMANDS]: Script engine found, module active"); 94 m_log.Info("[MODULE COMMANDS]: Script engine found, module active");
95 } 95 }
@@ -237,7 +237,7 @@ namespace OpenSim.Region.CoreModules.Scripting.ScriptModuleComms
237 } 237 }
238 } 238 }
239 } 239 }
240 240
241 public Delegate[] GetScriptInvocationList() 241 public Delegate[] GetScriptInvocationList()
242 { 242 {
243 List<Delegate> ret = new List<Delegate>(); 243 List<Delegate> ret = new List<Delegate>();
@@ -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 }
@@ -359,14 +361,14 @@ namespace OpenSim.Region.CoreModules.Scripting.ScriptModuleComms
359 public object LookupModConstant(string cname) 361 public object LookupModConstant(string cname)
360 { 362 {
361 // m_log.DebugFormat("[MODULE COMMANDS] lookup constant <{0}>",cname); 363 // m_log.DebugFormat("[MODULE COMMANDS] lookup constant <{0}>",cname);
362 364
363 lock (m_constants) 365 lock (m_constants)
364 { 366 {
365 object value = null; 367 object value = null;
366 if (m_constants.TryGetValue(cname,out value)) 368 if (m_constants.TryGetValue(cname,out value))
367 return value; 369 return value;
368 } 370 }
369 371
370 return null; 372 return null;
371 } 373 }
372 374
diff --git a/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs b/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs
index ed255bf..325f7f9 100644
--- a/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs
+++ b/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs
@@ -77,8 +77,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests
77 so.UUID, 77 so.UUID,
78 m_vrm.GetContentType(), 78 m_vrm.GetContentType(),
79 "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;", 79 "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;",
80 "", 80 "");
81 0);
82 81
83 Assert.That(originalTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID)); 82 Assert.That(originalTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
84 } 83 }
@@ -98,8 +97,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests
98 so.UUID, 97 so.UUID,
99 m_vrm.GetContentType(), 98 m_vrm.GetContentType(),
100 dtText, 99 dtText,
101 "", 100 "");
102 0);
103 101
104 UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID; 102 UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
105 103
@@ -108,8 +106,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests
108 so.UUID, 106 so.UUID,
109 m_vrm.GetContentType(), 107 m_vrm.GetContentType(),
110 dtText, 108 dtText,
111 "", 109 "");
112 0);
113 110
114 Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID)); 111 Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
115 } 112 }
@@ -129,8 +126,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests
129 so.UUID, 126 so.UUID,
130 m_vrm.GetContentType(), 127 m_vrm.GetContentType(),
131 dtText, 128 dtText,
132 "", 129 "");
133 0);
134 130
135 UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID; 131 UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
136 132
@@ -139,8 +135,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests
139 so.UUID, 135 so.UUID,
140 m_vrm.GetContentType(), 136 m_vrm.GetContentType(),
141 dtText, 137 dtText,
142 "alpha:250", 138 "alpha:250");
143 0);
144 139
145 Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID)); 140 Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
146 } 141 }
@@ -161,8 +156,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests
161 so.UUID, 156 so.UUID,
162 m_vrm.GetContentType(), 157 m_vrm.GetContentType(),
163 dtText, 158 dtText,
164 "", 159 "");
165 0);
166 160
167 UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID; 161 UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
168 162
@@ -171,8 +165,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests
171 so.UUID, 165 so.UUID,
172 m_vrm.GetContentType(), 166 m_vrm.GetContentType(),
173 dtText, 167 dtText,
174 "", 168 "");
175 0);
176 169
177 Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID)); 170 Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
178 } 171 }
@@ -191,8 +184,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests
191 so.UUID, 184 so.UUID,
192 m_vrm.GetContentType(), 185 m_vrm.GetContentType(),
193 "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;", 186 "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;",
194 "", 187 "");
195 0);
196 188
197 Assert.That(originalTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID)); 189 Assert.That(originalTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
198 } 190 }
@@ -213,8 +205,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests
213 so.UUID, 205 so.UUID,
214 m_vrm.GetContentType(), 206 m_vrm.GetContentType(),
215 dtText, 207 dtText,
216 "", 208 "");
217 0);
218 209
219 UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID; 210 UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
220 211
@@ -223,8 +214,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests
223 so.UUID, 214 so.UUID,
224 m_vrm.GetContentType(), 215 m_vrm.GetContentType(),
225 dtText, 216 dtText,
226 "", 217 "");
227 0);
228 218
229 Assert.That(firstDynamicTextureID, Is.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID)); 219 Assert.That(firstDynamicTextureID, Is.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
230 } 220 }
@@ -253,8 +243,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests
253 so.UUID, 243 so.UUID,
254 m_vrm.GetContentType(), 244 m_vrm.GetContentType(),
255 dtText, 245 dtText,
256 "1024", 246 "1024");
257 0);
258 247
259 UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID; 248 UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
260 249
@@ -263,8 +252,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests
263 so.UUID, 252 so.UUID,
264 m_vrm.GetContentType(), 253 m_vrm.GetContentType(),
265 dtText, 254 dtText,
266 "1024", 255 "1024");
267 0);
268 256
269 Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID)); 257 Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
270 } 258 }
@@ -284,8 +272,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests
284 so.UUID, 272 so.UUID,
285 m_vrm.GetContentType(), 273 m_vrm.GetContentType(),
286 dtText, 274 dtText,
287 "", 275 "");
288 0);
289 276
290 UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID; 277 UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
291 278
@@ -294,8 +281,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests
294 so.UUID, 281 so.UUID,
295 m_vrm.GetContentType(), 282 m_vrm.GetContentType(),
296 dtText, 283 dtText,
297 "alpha:250", 284 "alpha:250");
298 0);
299 285
300 Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID)); 286 Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
301 } 287 }
@@ -316,8 +302,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests
316 so.UUID, 302 so.UUID,
317 m_vrm.GetContentType(), 303 m_vrm.GetContentType(),
318 dtText, 304 dtText,
319 "", 305 "");
320 0);
321 306
322 UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID; 307 UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
323 308
@@ -326,8 +311,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests
326 so.UUID, 311 so.UUID,
327 m_vrm.GetContentType(), 312 m_vrm.GetContentType(),
328 dtText, 313 dtText,
329 "", 314 "");
330 0);
331 315
332 Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID)); 316 Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
333 } 317 }
diff --git a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs
index 4cecd85..8a26ab7 100644
--- a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs
@@ -117,7 +117,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
117 return true; 117 return true;
118 } 118 }
119 119
120 public void GetDrawStringSize(string text, string fontName, int fontSize, 120 public void GetDrawStringSize(string text, string fontName, int fontSize,
121 out double xSize, out double ySize) 121 out double xSize, out double ySize)
122 { 122 {
123 lock (this) 123 lock (this)
@@ -209,32 +209,32 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
209 int alpha = 255; // 0 is transparent 209 int alpha = 255; // 0 is transparent
210 Color bgColor = Color.White; // Default background color 210 Color bgColor = Color.White; // Default background color
211 char altDataDelim = ';'; 211 char altDataDelim = ';';
212 212
213 char[] paramDelimiter = { ',' }; 213 char[] paramDelimiter = { ',' };
214 char[] nvpDelimiter = { ':' }; 214 char[] nvpDelimiter = { ':' };
215 215
216 extraParams = extraParams.Trim(); 216 extraParams = extraParams.Trim();
217 extraParams = extraParams.ToLower(); 217 extraParams = extraParams.ToLower();
218 218
219 string[] nvps = extraParams.Split(paramDelimiter); 219 string[] nvps = extraParams.Split(paramDelimiter);
220 220
221 int temp = -1; 221 int temp = -1;
222 foreach (string pair in nvps) 222 foreach (string pair in nvps)
223 { 223 {
224 string[] nvp = pair.Split(nvpDelimiter); 224 string[] nvp = pair.Split(nvpDelimiter);
225 string name = ""; 225 string name = "";
226 string value = ""; 226 string value = "";
227 227
228 if (nvp[0] != null) 228 if (nvp[0] != null)
229 { 229 {
230 name = nvp[0].Trim(); 230 name = nvp[0].Trim();
231 } 231 }
232 232
233 if (nvp.Length == 2) 233 if (nvp.Length == 2)
234 { 234 {
235 value = nvp[1].Trim(); 235 value = nvp[1].Trim();
236 } 236 }
237 237
238 switch (name) 238 switch (name)
239 { 239 {
240 case "width": 240 case "width":
@@ -301,7 +301,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
301 if (Int32.TryParse(value, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out hex)) 301 if (Int32.TryParse(value, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out hex))
302 { 302 {
303 bgColor = Color.FromArgb(hex); 303 bgColor = Color.FromArgb(hex);
304 } 304 }
305 else 305 else
306 { 306 {
307 bgColor = Color.FromName(value); 307 bgColor = Color.FromName(value);
@@ -321,7 +321,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
321 } 321 }
322 else 322 else
323 { 323 {
324 // this function used to accept an int on its own that represented both 324 // this function used to accept an int on its own that represented both
325 // width and height, this is to maintain backwards compat, could be removed 325 // width and height, this is to maintain backwards compat, could be removed
326 // but would break existing scripts 326 // but would break existing scripts
327 temp = parseIntParam(name); 327 temp = parseIntParam(name);
@@ -329,10 +329,10 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
329 { 329 {
330 if (temp > 1024) 330 if (temp > 1024)
331 temp = 1024; 331 temp = 1024;
332 332
333 if (temp < 128) 333 if (temp < 128)
334 temp = 128; 334 temp = 128;
335 335
336 width = temp; 336 width = temp;
337 height = temp; 337 height = temp;
338 } 338 }
@@ -355,36 +355,28 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
355 lock (this) 355 lock (this)
356 { 356 {
357 if (alpha == 256) 357 if (alpha == 256)
358 bitmap = new Bitmap(width, height, PixelFormat.Format32bppRgb);
359 else
360 bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb);
361
362 graph = Graphics.FromImage(bitmap);
363
364 // this is really just to save people filling the
365 // background color in their scripts, only do when fully opaque
366 if (alpha >= 255)
367 { 358 {
359 bitmap = new Bitmap(width, height, PixelFormat.Format32bppRgb);
360 graph = Graphics.FromImage(bitmap);
368 using (SolidBrush bgFillBrush = new SolidBrush(bgColor)) 361 using (SolidBrush bgFillBrush = new SolidBrush(bgColor))
369 { 362 {
370 graph.FillRectangle(bgFillBrush, 0, 0, width, height); 363 graph.FillRectangle(bgFillBrush, 0, 0, width, height);
371 } 364 }
372 } 365 }
373 366 else
374 for (int w = 0; w < bitmap.Width; w++)
375 { 367 {
376 if (alpha <= 255) 368 bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb);
369 graph = Graphics.FromImage(bitmap);
370 Color newbg = Color.FromArgb(alpha,bgColor);
371 using (SolidBrush bgFillBrush = new SolidBrush(newbg))
377 { 372 {
378 for (int h = 0; h < bitmap.Height; h++) 373 graph.FillRectangle(bgFillBrush, 0, 0, width, height);
379 {
380 bitmap.SetPixel(w, h, Color.FromArgb(alpha, bitmap.GetPixel(w, h)));
381 }
382 } 374 }
383 } 375 }
384 376
385 GDIDraw(data, graph, altDataDelim, out reuseable); 377 GDIDraw(data, graph, altDataDelim, out reuseable);
386 } 378 }
387 379
388 byte[] imageJ2000 = new byte[0]; 380 byte[] imageJ2000 = new byte[0];
389 381
390 // This code exists for testing purposes, please do not remove. 382 // This code exists for testing purposes, please do not remove.
@@ -394,7 +386,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
394// imageJ2000 = s_asset2Data; 386// imageJ2000 = s_asset2Data;
395// 387//
396// s_flipper = !s_flipper; 388// s_flipper = !s_flipper;
397 389
398 try 390 try
399 { 391 {
400 imageJ2000 = OpenJPEG.EncodeFromImage(bitmap, true); 392 imageJ2000 = OpenJPEG.EncodeFromImage(bitmap, true);
@@ -420,13 +412,13 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
420 { 412 {
421 if (graph != null) 413 if (graph != null)
422 graph.Dispose(); 414 graph.Dispose();
423 415
424 if (bitmap != null) 416 if (bitmap != null)
425 bitmap.Dispose(); 417 bitmap.Dispose();
426 } 418 }
427 } 419 }
428 } 420 }
429 421
430 private int parseIntParam(string strInt) 422 private int parseIntParam(string strInt)
431 { 423 {
432 int parsed; 424 int parsed;
@@ -440,7 +432,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
440 // m_log.Debug("Problem with Draw. Please verify parameters." + e.ToString()); 432 // m_log.Debug("Problem with Draw. Please verify parameters." + e.ToString());
441 parsed = -1; 433 parsed = -1;
442 } 434 }
443 435
444 return parsed; 436 return parsed;
445 } 437 }
446 438
@@ -519,8 +511,32 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
519 511
520// m_log.DebugFormat("[VECTOR RENDER MODULE]: Processing line '{0}'", nextLine); 512// m_log.DebugFormat("[VECTOR RENDER MODULE]: Processing line '{0}'", nextLine);
521 513
514 if (nextLine.StartsWith("ResetTransf"))
515 {
516 graph.ResetTransform();
517 }
518 else if (nextLine.StartsWith("TransTransf"))
519 {
520 float x = 0;
521 float y = 0;
522 GetParams(partsDelimiter, ref nextLine, 11, ref x, ref y);
523 graph.TranslateTransform(x, y);
524 }
525 else if (nextLine.StartsWith("ScaleTransf"))
526 {
527 float x = 0;
528 float y = 0;
529 GetParams(partsDelimiter, ref nextLine, 11, ref x, ref y);
530 graph.ScaleTransform(x, y);
531 }
532 else if (nextLine.StartsWith("RotTransf"))
533 {
534 float x = 0;
535 GetParams(partsDelimiter, ref nextLine, 9, ref x);
536 graph.RotateTransform(x);
537 }
522 //replace with switch, or even better, do some proper parsing 538 //replace with switch, or even better, do some proper parsing
523 if (nextLine.StartsWith("MoveTo")) 539 else if (nextLine.StartsWith("MoveTo"))
524 { 540 {
525 float x = 0; 541 float x = 0;
526 float y = 0; 542 float y = 0;
@@ -572,7 +588,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
572 graph.DrawString("not an image. Please check URL.", errorFont, 588 graph.DrawString("not an image. Please check URL.", errorFont,
573 myBrush, new Point(startPoint.X, 12 + startPoint.Y)); 589 myBrush, new Point(startPoint.X, 12 + startPoint.Y));
574 } 590 }
575 591
576 graph.DrawRectangle(drawPen, startPoint.X, startPoint.Y, endPoint.X, endPoint.Y); 592 graph.DrawRectangle(drawPen, startPoint.X, startPoint.Y, endPoint.X, endPoint.Y);
577 } 593 }
578 } 594 }
@@ -625,6 +641,17 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
625 startPoint.X += endPoint.X; 641 startPoint.X += endPoint.X;
626 startPoint.Y += endPoint.Y; 642 startPoint.Y += endPoint.Y;
627 } 643 }
644 else if (nextLine.StartsWith("FillEllipse"))
645 {
646 float x = 0;
647 float y = 0;
648 GetParams(partsDelimiter, ref nextLine, 11, ref x, ref y);
649 endPoint.X = (int)x;
650 endPoint.Y = (int)y;
651 graph.FillEllipse(myBrush, startPoint.X, startPoint.Y, endPoint.X, endPoint.Y);
652 startPoint.X += endPoint.X;
653 startPoint.Y += endPoint.Y;
654 }
628 else if (nextLine.StartsWith("FontSize")) 655 else if (nextLine.StartsWith("FontSize"))
629 { 656 {
630 nextLine = nextLine.Remove(0, 8); 657 nextLine = nextLine.Remove(0, 8);
@@ -638,11 +665,11 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
638 { 665 {
639 nextLine = nextLine.Remove(0, 8); 666 nextLine = nextLine.Remove(0, 8);
640 nextLine = nextLine.Trim(); 667 nextLine = nextLine.Trim();
641 668
642 string[] fprops = nextLine.Split(partsDelimiter); 669 string[] fprops = nextLine.Split(partsDelimiter);
643 foreach (string prop in fprops) 670 foreach (string prop in fprops)
644 { 671 {
645 672
646 switch (prop) 673 switch (prop)
647 { 674 {
648 case "B": 675 case "B":
@@ -717,7 +744,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
717 else if (cap[0].ToLower() != "both") 744 else if (cap[0].ToLower() != "both")
718 return; 745 return;
719 string type = cap[1].ToLower(); 746 string type = cap[1].ToLower();
720 747
721 if (end) 748 if (end)
722 { 749 {
723 switch (type) 750 switch (type)
@@ -760,7 +787,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
760 nextLine = nextLine.Remove(0, 9); 787 nextLine = nextLine.Remove(0, 9);
761 nextLine = nextLine.Trim(); 788 nextLine = nextLine.Trim();
762 int hex = 0; 789 int hex = 0;
763 790
764 Color newColor; 791 Color newColor;
765 if (Int32.TryParse(nextLine, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out hex)) 792 if (Int32.TryParse(nextLine, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out hex))
766 { 793 {
@@ -790,6 +817,17 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
790 } 817 }
791 } 818 }
792 819
820 private static void GetParams(char[] partsDelimiter, ref string line, int startLength, ref float x)
821 {
822 line = line.Remove(0, startLength);
823 string[] parts = line.Split(partsDelimiter);
824 if (parts.Length > 0)
825 {
826 string xVal = parts[0].Trim();
827 x = Convert.ToSingle(xVal, CultureInfo.InvariantCulture);
828 }
829 }
830
793 private static void GetParams(char[] partsDelimiter, ref string line, int startLength, ref float x, ref float y) 831 private static void GetParams(char[] partsDelimiter, ref string line, int startLength, ref float x, ref float y)
794 { 832 {
795 line = line.Remove(0, startLength); 833 line = line.Remove(0, startLength);
@@ -861,4 +899,4 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
861 return null; 899 return null;
862 } 900 }
863 } 901 }
864} \ No newline at end of file 902}
diff --git a/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs b/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs
index 3484387..a5203ea 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;
@@ -111,7 +113,7 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
111 // wrap this in a try block so that defaults will work if 113 // wrap this in a try block so that defaults will work if
112 // the config file doesn't specify otherwise. 114 // the config file doesn't specify otherwise.
113 int maxlisteners = 1000; 115 int maxlisteners = 1000;
114 int maxhandles = 64; 116 int maxhandles = 65;
115 try 117 try
116 { 118 {
117 m_whisperdistance = config.Configs["Chat"].GetInt( 119 m_whisperdistance = config.Configs["Chat"].GetInt(
@@ -128,8 +130,15 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
128 catch (Exception) 130 catch (Exception)
129 { 131 {
130 } 132 }
131 if (maxlisteners < 1) maxlisteners = int.MaxValue; 133
132 if (maxhandles < 1) maxhandles = int.MaxValue; 134 if (maxlisteners < 1)
135 maxlisteners = int.MaxValue;
136 if (maxhandles < 1)
137 maxhandles = int.MaxValue;
138
139 if (maxlisteners < maxhandles)
140 maxlisteners = maxhandles;
141
133 m_listenerManager = new ListenerManager(maxlisteners, maxhandles); 142 m_listenerManager = new ListenerManager(maxlisteners, maxhandles);
134 m_pendingQ = new Queue(); 143 m_pendingQ = new Queue();
135 m_pending = Queue.Synchronized(m_pendingQ); 144 m_pending = Queue.Synchronized(m_pendingQ);
@@ -309,6 +318,7 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
309 // Determine which listen event filters match the given set of arguments, this results 318 // Determine which listen event filters match the given set of arguments, this results
310 // in a limited set of listeners, each belonging a host. If the host is in range, add them 319 // in a limited set of listeners, each belonging a host. If the host is in range, add them
311 // to the pending queue. 320 // to the pending queue.
321
312 foreach (ListenerInfo li 322 foreach (ListenerInfo li
313 in m_listenerManager.GetListeners(UUID.Zero, channel, 323 in m_listenerManager.GetListeners(UUID.Zero, channel,
314 name, id, msg)) 324 name, id, msg))
@@ -366,79 +376,82 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
366 /// <param name='msg'> 376 /// <param name='msg'>
367 /// Message. 377 /// Message.
368 /// </param> 378 /// </param>
369 public void DeliverMessageTo(UUID target, int channel, Vector3 pos, 379 public void DeliverMessageTo(UUID target, int channel, Vector3 pos, string name, UUID id, string msg)
370 string name, UUID id, string msg)
371 { 380 {
372 // Is id an avatar? 381 if (channel == DEBUG_CHANNEL)
373 ScenePresence sp = m_scene.GetScenePresence(target); 382 return;
374 383
384 if(target == UUID.Zero)
385 return;
386
387 // Is target an avatar?
388 ScenePresence sp = m_scene.GetScenePresence(target);
375 if (sp != null) 389 if (sp != null)
376 { 390 {
377 // ignore if a child agent this is restricted to inside one 391 // Send message to avatar
378 // region 392 if (channel == 0)
379 if (sp.IsChildAgent) 393 {
394 // Channel 0 goes to viewer ONLY
395 m_scene.SimChat(Utils.StringToBytes(msg), ChatTypeEnum.Broadcast, 0, pos, name, id, target, false, false);
380 return; 396 return;
397 }
381 398
382 // Channel zero only goes to the avatar 399 // for now messages to prims don't cross regions
383 // non zero channel messages only go to the attachments of the avatar. 400 if(sp.IsChildAgent)
384 if (channel != 0) 401 return;
385 {
386 List<SceneObjectGroup> attachments = sp.GetAttachments();
387 if (attachments.Count == 0)
388 return;
389 402
390 // Get uuid of attachments 403 List<SceneObjectGroup> attachments = sp.GetAttachments();
391 List<UUID> targets = new List<UUID>(); 404
392 foreach (SceneObjectGroup sog in attachments) 405 if (attachments.Count == 0)
393 { 406 return;
394 if (!sog.IsDeleted)
395 targets.Add(sog.UUID);
396 }
397 407
398 // Need to check each attachment 408 // Get uuid of attachments
399 foreach (ListenerInfo li 409 List<UUID> targets = new List<UUID>();
400 in m_listenerManager.GetListeners(UUID.Zero, 410 foreach (SceneObjectGroup sog in attachments)
401 channel, name, id, msg)) 411 {
412 if (!sog.IsDeleted)
402 { 413 {
403 if (li.GetHostID().Equals(id)) 414 SceneObjectPart[] parts = sog.Parts;
404 continue; 415 foreach(SceneObjectPart p in parts)
416 targets.Add(p.UUID);
417 }
418 }
405 419
406 if (m_scene.GetSceneObjectPart( 420 foreach (ListenerInfo li in m_listenerManager.GetListeners(UUID.Zero, channel, name, id, msg))
407 li.GetHostID()) == null) 421 {
408 { 422 UUID liHostID = li.GetHostID();
409 continue; 423 if (liHostID.Equals(id))
410 } 424 continue;
425 if (m_scene.GetSceneObjectPart(liHostID) == null)
426 continue;
411 427
412 if (targets.Contains(li.GetHostID())) 428 if (targets.Contains(liHostID))
413 QueueMessage(new ListenerInfo(li, name, id, msg)); 429 QueueMessage(new ListenerInfo(li, name, id, msg));
414 }
415 } 430 }
416 431
417 return; 432 return;
418 } 433 }
419 434
420 // No avatar found so look for an object 435 SceneObjectPart part = m_scene.GetSceneObjectPart(target);
421 foreach (ListenerInfo li 436 if (part == null) // Not even an object
422 in m_listenerManager.GetListeners(UUID.Zero, channel, 437 return; // No error
423 name, id, msg)) 438
439 foreach (ListenerInfo li in m_listenerManager.GetListeners(UUID.Zero, channel, name, id, msg))
424 { 440 {
441 UUID liHostID = li.GetHostID();
425 // Dont process if this message is from yourself! 442 // Dont process if this message is from yourself!
426 if (li.GetHostID().Equals(id)) 443 if (liHostID.Equals(id))
427 continue; 444 continue;
428 445
429 SceneObjectPart sPart = m_scene.GetSceneObjectPart( 446 if (m_scene.GetSceneObjectPart(liHostID) == null)
430 li.GetHostID());
431 if (sPart == null)
432 continue; 447 continue;
433 448
434 if (li.GetHostID().Equals(target)) 449 if (liHostID.Equals(target))
435 { 450 {
436 QueueMessage(new ListenerInfo(li, name, id, msg)); 451 QueueMessage(new ListenerInfo(li, name, id, msg));
437 break; 452 break;
438 } 453 }
439 } 454 }
440
441 return;
442 } 455 }
443 456
444 protected void QueueMessage(ListenerInfo li) 457 protected void QueueMessage(ListenerInfo li)
@@ -557,9 +570,9 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
557 return coll[0].GetHandle(); 570 return coll[0].GetHandle();
558 } 571 }
559 572
560 if (m_curlisteners < m_maxlisteners) 573 lock (m_listeners)
561 { 574 {
562 lock (m_listeners) 575 if (m_curlisteners < m_maxlisteners)
563 { 576 {
564 int newHandle = GetNewHandle(itemID); 577 int newHandle = GetNewHandle(itemID);
565 578
@@ -599,11 +612,9 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
599 li.GetHandle().Equals(handle)) 612 li.GetHandle().Equals(handle))
600 { 613 {
601 lis.Value.Remove(li); 614 lis.Value.Remove(li);
615 m_curlisteners--;
602 if (lis.Value.Count == 0) 616 if (lis.Value.Count == 0)
603 { 617 m_listeners.Remove(lis.Key); // bailing of loop so this does not smoke
604 m_listeners.Remove(lis.Key);
605 m_curlisteners--;
606 }
607 // there should be only one, so we bail out early 618 // there should be only one, so we bail out early
608 return; 619 return;
609 } 620 }
@@ -712,6 +723,9 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
712 } 723 }
713 } 724 }
714 725
726 if(handles.Count >= m_maxhandles)
727 return -1;
728
715 // Note: 0 is NOT a valid handle for llListen() to return 729 // Note: 0 is NOT a valid handle for llListen() to return
716 for (int i = 1; i <= m_maxhandles; i++) 730 for (int i = 1; i <= m_maxhandles; i++)
717 { 731 {
diff --git a/OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs b/OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs
index 87f4277..6028eef 100644
--- a/OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs
@@ -621,7 +621,7 @@ namespace OpenSim.Region.CoreModules.Scripting.XMLRPC
621 private Thread httpThread; 621 private Thread httpThread;
622 public int Idata; 622 public int Idata;
623 private UUID _itemID; 623 private UUID _itemID;
624 public UUID ItemID 624 public UUID ItemID
625 { 625 {
626 get { return _itemID; } 626 get { return _itemID; }
627 set { _itemID = value; } 627 set { _itemID = value; }
@@ -633,7 +633,7 @@ namespace OpenSim.Region.CoreModules.Scripting.XMLRPC
633 set { _localID = value; } 633 set { _localID = value; }
634 } 634 }
635 private UUID _reqID; 635 private UUID _reqID;
636 public UUID ReqID 636 public UUID ReqID
637 { 637 {
638 get { return _reqID; } 638 get { return _reqID; }
639 set { _reqID = value; } 639 set { _reqID = value; }
@@ -658,7 +658,7 @@ namespace OpenSim.Region.CoreModules.Scripting.XMLRPC
658 public void Process() 658 public void Process()
659 { 659 {
660 _finished = false; 660 _finished = false;
661 httpThread = WorkManager.StartThread(SendRequest, "HttpRequestThread", ThreadPriority.BelowNormal, true, false); 661 httpThread = WorkManager.StartThread(SendRequest, "XMLRPCreqThread", ThreadPriority.BelowNormal, true, false, null, int.MaxValue);
662 } 662 }
663 663
664 /* 664 /*