aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs64
-rw-r--r--OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs169
-rw-r--r--OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs12
-rw-r--r--OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs239
-rw-r--r--OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs60
-rw-r--r--OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs61
-rw-r--r--OpenSim/Region/Framework/Interfaces/IDynamicTextureManager.cs16
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs36
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs46
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs59
12 files changed, 617 insertions, 149 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs
index b112b6d..12a05b3 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs
@@ -350,38 +350,38 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
350 Assert.That(sog1.RootPart.CreatorID, Is.EqualTo(m_uaLL1.PrincipalID)); 350 Assert.That(sog1.RootPart.CreatorID, Is.EqualTo(m_uaLL1.PrincipalID));
351 } 351 }
352 352
353 /// <summary> 353// /// <summary>
354 /// Test loading a V0.1 OpenSim Inventory Archive (subject to change since there is no fixed format yet) where 354// /// Test loading a V0.1 OpenSim Inventory Archive (subject to change since there is no fixed format yet) where
355 /// an account exists with the same name as the creator, though not the same id. 355// /// an account exists with the same name as the creator, though not the same id.
356 /// </summary> 356// /// </summary>
357 [Test] 357// [Test]
358 public void TestLoadIarV0_1SameNameCreator() 358// public void TestLoadIarV0_1SameNameCreator()
359 { 359// {
360 TestHelpers.InMethod(); 360// TestHelpers.InMethod();
361// log4net.Config.XmlConfigurator.Configure(); 361// TestHelpers.EnableLogging();
362 362//
363 UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaMT, "meowfood"); 363// UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaMT, "meowfood");
364 UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaLL2, "hampshire"); 364// UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaLL2, "hampshire");
365 365//
366 m_archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "/", "meowfood", m_iarStream); 366// m_archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "/", "meowfood", m_iarStream);
367 InventoryItemBase foundItem1 367// InventoryItemBase foundItem1
368 = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, m_uaMT.PrincipalID, m_item1Name); 368// = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, m_uaMT.PrincipalID, m_item1Name);
369 369//
370 Assert.That( 370// Assert.That(
371 foundItem1.CreatorId, Is.EqualTo(m_uaLL2.PrincipalID.ToString()), 371// foundItem1.CreatorId, Is.EqualTo(m_uaLL2.PrincipalID.ToString()),
372 "Loaded item non-uuid creator doesn't match original"); 372// "Loaded item non-uuid creator doesn't match original");
373 Assert.That( 373// Assert.That(
374 foundItem1.CreatorIdAsUuid, Is.EqualTo(m_uaLL2.PrincipalID), 374// foundItem1.CreatorIdAsUuid, Is.EqualTo(m_uaLL2.PrincipalID),
375 "Loaded item uuid creator doesn't match original"); 375// "Loaded item uuid creator doesn't match original");
376 Assert.That(foundItem1.Owner, Is.EqualTo(m_uaMT.PrincipalID), 376// Assert.That(foundItem1.Owner, Is.EqualTo(m_uaMT.PrincipalID),
377 "Loaded item owner doesn't match inventory reciever"); 377// "Loaded item owner doesn't match inventory reciever");
378 378//
379 AssetBase asset1 = m_scene.AssetService.Get(foundItem1.AssetID.ToString()); 379// AssetBase asset1 = m_scene.AssetService.Get(foundItem1.AssetID.ToString());
380 string xmlData = Utils.BytesToString(asset1.Data); 380// string xmlData = Utils.BytesToString(asset1.Data);
381 SceneObjectGroup sog1 = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); 381// SceneObjectGroup sog1 = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
382 382//
383 Assert.That(sog1.RootPart.CreatorID, Is.EqualTo(m_uaLL2.PrincipalID)); 383// Assert.That(sog1.RootPart.CreatorID, Is.EqualTo(m_uaLL2.PrincipalID));
384 } 384// }
385 385
386 /// <summary> 386 /// <summary>
387 /// Test loading a V0.1 OpenSim Inventory Archive (subject to change since there is no fixed format yet) where 387 /// Test loading a V0.1 OpenSim Inventory Archive (subject to change since there is no fixed format yet) where
diff --git a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs
index 18bd018..13b7498 100644
--- a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs
@@ -49,6 +49,11 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
49 public const int DISP_EXPIRE = 1; 49 public const int DISP_EXPIRE = 1;
50 public const int DISP_TEMP = 2; 50 public const int DISP_TEMP = 2;
51 51
52 /// <summary>
53 /// If true then where possible dynamic textures are reused.
54 /// </summary>
55 public bool ReuseTextures { get; set; }
56
52 private Dictionary<UUID, Scene> RegisteredScenes = new Dictionary<UUID, Scene>(); 57 private Dictionary<UUID, Scene> RegisteredScenes = new Dictionary<UUID, Scene>();
53 58
54 private Dictionary<string, IDynamicTextureRender> RenderPlugins = 59 private Dictionary<string, IDynamicTextureRender> RenderPlugins =
@@ -56,6 +61,15 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
56 61
57 private Dictionary<UUID, DynamicTextureUpdater> Updaters = new Dictionary<UUID, DynamicTextureUpdater>(); 62 private Dictionary<UUID, DynamicTextureUpdater> Updaters = new Dictionary<UUID, DynamicTextureUpdater>();
58 63
64 /// <summary>
65 /// Record dynamic textures that we can reuse for a given data and parameter combination rather than
66 /// regenerate.
67 /// </summary>
68 /// <remarks>
69 /// Key is string.Format("{0}{1}", data
70 /// </remarks>
71 private Cache m_reuseableDynamicTextures;
72
59 #region IDynamicTextureManager Members 73 #region IDynamicTextureManager Members
60 74
61 public void RegisterRender(string handleType, IDynamicTextureRender render) 75 public void RegisterRender(string handleType, IDynamicTextureRender render)
@@ -71,7 +85,8 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
71 /// </summary> 85 /// </summary>
72 /// <param name="id"></param> 86 /// <param name="id"></param>
73 /// <param name="data"></param> 87 /// <param name="data"></param>
74 public void ReturnData(UUID id, byte[] data) 88 /// <param name="isReuseable">True if the data generated can be reused for subsequent identical requests</param>
89 public void ReturnData(UUID id, byte[] data, bool isReuseable)
75 { 90 {
76 DynamicTextureUpdater updater = null; 91 DynamicTextureUpdater updater = null;
77 92
@@ -88,7 +103,11 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
88 if (RegisteredScenes.ContainsKey(updater.SimUUID)) 103 if (RegisteredScenes.ContainsKey(updater.SimUUID))
89 { 104 {
90 Scene scene = RegisteredScenes[updater.SimUUID]; 105 Scene scene = RegisteredScenes[updater.SimUUID];
91 updater.DataReceived(data, scene); 106 UUID newTextureID = updater.DataReceived(data, scene);
107
108 if (ReuseTextures && isReuseable && !updater.BlendWithOldTexture)
109 m_reuseableDynamicTextures.Store(
110 GenerateReusableTextureKey(updater.BodyData, updater.Params), newTextureID);
92 } 111 }
93 } 112 }
94 113
@@ -169,6 +188,11 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
169 { 188 {
170 if (RenderPlugins.ContainsKey(contentType)) 189 if (RenderPlugins.ContainsKey(contentType))
171 { 190 {
191 // If we want to reuse dynamic textures then we have to ignore any request from the caller to expire
192 // them.
193 if (ReuseTextures)
194 disp = disp & ~DISP_EXPIRE;
195
172 DynamicTextureUpdater updater = new DynamicTextureUpdater(); 196 DynamicTextureUpdater updater = new DynamicTextureUpdater();
173 updater.SimUUID = simID; 197 updater.SimUUID = simID;
174 updater.PrimID = primID; 198 updater.PrimID = primID;
@@ -183,21 +207,49 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
183 updater.Url = "Local image"; 207 updater.Url = "Local image";
184 updater.Disp = disp; 208 updater.Disp = disp;
185 209
186 lock (Updaters) 210 object reusableTextureUUID = null;
211
212 if (ReuseTextures)
213 reusableTextureUUID
214 = m_reuseableDynamicTextures.Get(GenerateReusableTextureKey(data, extraParams));
215
216 // We cannot reuse a dynamic texture if the data is going to be blended with something already there.
217 if (reusableTextureUUID == null || updater.BlendWithOldTexture)
187 { 218 {
188 if (!Updaters.ContainsKey(updater.UpdaterID)) 219 lock (Updaters)
189 { 220 {
190 Updaters.Add(updater.UpdaterID, updater); 221 if (!Updaters.ContainsKey(updater.UpdaterID))
222 {
223 Updaters.Add(updater.UpdaterID, updater);
224 }
225 }
226
227 RenderPlugins[contentType].AsyncConvertData(updater.UpdaterID, data, extraParams);
228 }
229 else
230 {
231 // No need to add to updaters as the texture is always the same. Not that this functionality
232 // apppears to be implemented anyway.
233 if (RegisteredScenes.ContainsKey(updater.SimUUID))
234 {
235 SceneObjectPart part = RegisteredScenes[updater.SimUUID].GetSceneObjectPart(updater.PrimID);
236
237 if (part != null)
238 updater.UpdatePart(part, (UUID)reusableTextureUUID);
191 } 239 }
192 } 240 }
193 241
194 RenderPlugins[contentType].AsyncConvertData(updater.UpdaterID, data, extraParams);
195 return updater.UpdaterID; 242 return updater.UpdaterID;
196 } 243 }
197 244
198 return UUID.Zero; 245 return UUID.Zero;
199 } 246 }
200 247
248 private string GenerateReusableTextureKey(string data, string extraParams)
249 {
250 return string.Format("{0}{1}", data, extraParams);
251 }
252
201 public void GetDrawStringSize(string contentType, string text, string fontName, int fontSize, 253 public void GetDrawStringSize(string contentType, string text, string fontName, int fontSize,
202 out double xSize, out double ySize) 254 out double xSize, out double ySize)
203 { 255 {
@@ -224,6 +276,12 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
224 276
225 public void PostInitialise() 277 public void PostInitialise()
226 { 278 {
279// ReuseTextures = true;
280 if (ReuseTextures)
281 {
282 m_reuseableDynamicTextures = new Cache(CacheMedium.Memory, CacheStrategy.Conservative);
283 m_reuseableDynamicTextures.DefaultTTL = new TimeSpan(24, 0, 0);
284 }
227 } 285 }
228 286
229 public void Close() 287 public void Close()
@@ -269,9 +327,60 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
269 } 327 }
270 328
271 /// <summary> 329 /// <summary>
330 /// Update the given part with the new texture.
331 /// </summary>
332 /// <returns>
333 /// The old texture UUID.
334 /// </returns>
335 public UUID UpdatePart(SceneObjectPart part, UUID textureID)
336 {
337 UUID oldID;
338
339 lock (part)
340 {
341 // mostly keep the values from before
342 Primitive.TextureEntry tmptex = part.Shape.Textures;
343
344 // FIXME: Need to return the appropriate ID if only a single face is replaced.
345 oldID = tmptex.DefaultTexture.TextureID;
346
347 if (Face == ALL_SIDES)
348 {
349 oldID = tmptex.DefaultTexture.TextureID;
350 tmptex.DefaultTexture.TextureID = textureID;
351 }
352 else
353 {
354 try
355 {
356 Primitive.TextureEntryFace texface = tmptex.CreateFace((uint)Face);
357 texface.TextureID = textureID;
358 tmptex.FaceTextures[Face] = texface;
359 }
360 catch (Exception)
361 {
362 tmptex.DefaultTexture.TextureID = textureID;
363 }
364 }
365
366 // I'm pretty sure we always want to force this to true
367 // I'm pretty sure noone whats to set fullbright true if it wasn't true before.
368 // tmptex.DefaultTexture.Fullbright = true;
369
370 part.UpdateTextureEntry(tmptex.GetBytes());
371 }
372
373 return oldID;
374 }
375
376 /// <summary>
272 /// Called once new texture data has been received for this updater. 377 /// Called once new texture data has been received for this updater.
273 /// </summary> 378 /// </summary>
274 public void DataReceived(byte[] data, Scene scene) 379 /// <param name="data"></param>
380 /// <param name="scene"></param>
381 /// <param name="isReuseable">True if the data given is reuseable.</param>
382 /// <returns>The asset UUID given to the incoming data.</returns>
383 public UUID DataReceived(byte[] data, Scene scene)
275 { 384 {
276 SceneObjectPart part = scene.GetSceneObjectPart(PrimID); 385 SceneObjectPart part = scene.GetSceneObjectPart(PrimID);
277 386
@@ -281,7 +390,8 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
281 String.Format("DynamicTextureModule: Error preparing image using URL {0}", Url); 390 String.Format("DynamicTextureModule: Error preparing image using URL {0}", Url);
282 scene.SimChat(Utils.StringToBytes(msg), ChatTypeEnum.Say, 391 scene.SimChat(Utils.StringToBytes(msg), ChatTypeEnum.Say,
283 0, part.ParentGroup.RootPart.AbsolutePosition, part.Name, part.UUID, false); 392 0, part.ParentGroup.RootPart.AbsolutePosition, part.Name, part.UUID, false);
284 return; 393
394 return UUID.Zero;
285 } 395 }
286 396
287 byte[] assetData = null; 397 byte[] assetData = null;
@@ -323,52 +433,23 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
323 cacheLayerDecode = null; 433 cacheLayerDecode = null;
324 } 434 }
325 435
326 UUID oldID = UUID.Zero; 436 UUID oldID = UpdatePart(part, asset.FullID);
327
328 lock (part)
329 {
330 // mostly keep the values from before
331 Primitive.TextureEntry tmptex = part.Shape.Textures;
332
333 // remove the old asset from the cache
334 oldID = tmptex.DefaultTexture.TextureID;
335
336 if (Face == ALL_SIDES)
337 {
338 tmptex.DefaultTexture.TextureID = asset.FullID;
339 }
340 else
341 {
342 try
343 {
344 Primitive.TextureEntryFace texface = tmptex.CreateFace((uint)Face);
345 texface.TextureID = asset.FullID;
346 tmptex.FaceTextures[Face] = texface;
347 }
348 catch (Exception)
349 {
350 tmptex.DefaultTexture.TextureID = asset.FullID;
351 }
352 }
353
354 // I'm pretty sure we always want to force this to true
355 // I'm pretty sure noone whats to set fullbright true if it wasn't true before.
356 // tmptex.DefaultTexture.Fullbright = true;
357
358 part.UpdateTextureEntry(tmptex.GetBytes());
359 }
360 437
361 if (oldID != UUID.Zero && ((Disp & DISP_EXPIRE) != 0)) 438 if (oldID != UUID.Zero && ((Disp & DISP_EXPIRE) != 0))
362 { 439 {
363 if (oldAsset == null) oldAsset = scene.AssetService.Get(oldID.ToString()); 440 if (oldAsset == null)
441 oldAsset = scene.AssetService.Get(oldID.ToString());
442
364 if (oldAsset != null) 443 if (oldAsset != null)
365 { 444 {
366 if (oldAsset.Temporary == true) 445 if (oldAsset.Temporary)
367 { 446 {
368 scene.AssetService.Delete(oldID.ToString()); 447 scene.AssetService.Delete(oldID.ToString());
369 } 448 }
370 } 449 }
371 } 450 }
451
452 return asset.FullID;
372 } 453 }
373 454
374 private byte[] BlendTextures(byte[] frontImage, byte[] backImage, bool setNewAlpha, byte newAlpha) 455 private byte[] BlendTextures(byte[] frontImage, byte[] backImage, bool setNewAlpha, byte newAlpha)
diff --git a/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs b/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs
index 6f83948..2b3a0f2 100644
--- a/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs
@@ -67,12 +67,18 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL
67 return true; 67 return true;
68 } 68 }
69 69
70// public bool AlwaysIdenticalConversion(string bodyData, string extraParams)
71// {
72// // We don't support conversion of body data.
73// return false;
74// }
75
70 public byte[] ConvertUrl(string url, string extraParams) 76 public byte[] ConvertUrl(string url, string extraParams)
71 { 77 {
72 return null; 78 return null;
73 } 79 }
74 80
75 public byte[] ConvertStream(Stream data, string extraParams) 81 public byte[] ConvertData(string bodyData, string extraParams)
76 { 82 {
77 return null; 83 return null;
78 } 84 }
@@ -236,9 +242,11 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL
236 stream.Close(); 242 stream.Close();
237 } 243 }
238 } 244 }
245
239 m_log.DebugFormat("[LOADIMAGEURLMODULE] Returning {0} bytes of image data for request {1}", 246 m_log.DebugFormat("[LOADIMAGEURLMODULE] Returning {0} bytes of image data for request {1}",
240 imageJ2000.Length, state.RequestID); 247 imageJ2000.Length, state.RequestID);
241 m_textureManager.ReturnData(state.RequestID, imageJ2000); 248
249 m_textureManager.ReturnData(state.RequestID, imageJ2000, false);
242 } 250 }
243 251
244 #region Nested type: RequestState 252 #region Nested type: RequestState
diff --git a/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs b/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs
index 9787c8c..b50c0bd 100644
--- a/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs
+++ b/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs
@@ -45,31 +45,250 @@ using OpenSim.Tests.Common.Mock;
45namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests 45namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests
46{ 46{
47 [TestFixture] 47 [TestFixture]
48 public class VectorRenderModuleTests 48 public class VectorRenderModuleTests : OpenSimTestCase
49 { 49 {
50 Scene m_scene;
51 DynamicTextureModule m_dtm;
52 VectorRenderModule m_vrm;
53
54 private void SetupScene(bool reuseTextures)
55 {
56 m_scene = new SceneHelpers().SetupScene();
57
58 m_dtm = new DynamicTextureModule();
59 m_dtm.ReuseTextures = reuseTextures;
60
61 m_vrm = new VectorRenderModule();
62
63 SceneHelpers.SetupSceneModules(m_scene, m_dtm, m_vrm);
64 }
65
50 [Test] 66 [Test]
51 public void TestDraw() 67 public void TestDraw()
52 { 68 {
53 TestHelpers.InMethod(); 69 TestHelpers.InMethod();
54 70
55 Scene scene = new SceneHelpers().SetupScene(); 71 SetupScene(false);
56 DynamicTextureModule dtm = new DynamicTextureModule(); 72 SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
57 VectorRenderModule vrm = new VectorRenderModule();
58 SceneHelpers.SetupSceneModules(scene, dtm, vrm);
59
60 SceneObjectGroup so = SceneHelpers.AddSceneObject(scene);
61 UUID originalTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID; 73 UUID originalTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
62 74
63 dtm.AddDynamicTextureData( 75 m_dtm.AddDynamicTextureData(
64 scene.RegionInfo.RegionID, 76 m_scene.RegionInfo.RegionID,
65 so.UUID, 77 so.UUID,
66 vrm.GetContentType(), 78 m_vrm.GetContentType(),
67 "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;", 79 "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;",
68 "", 80 "",
69 0); 81 0);
70 82
83 Assert.That(originalTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
84 }
85
86 [Test]
87 public void TestRepeatSameDraw()
88 {
89 TestHelpers.InMethod();
90
91 string dtText = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;";
92
93 SetupScene(false);
94 SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
95
96 m_dtm.AddDynamicTextureData(
97 m_scene.RegionInfo.RegionID,
98 so.UUID,
99 m_vrm.GetContentType(),
100 dtText,
101 "",
102 0);
103
104 UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
105
106 m_dtm.AddDynamicTextureData(
107 m_scene.RegionInfo.RegionID,
108 so.UUID,
109 m_vrm.GetContentType(),
110 dtText,
111 "",
112 0);
113
114 Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
115 }
116
117 [Test]
118 public void TestRepeatSameDrawDifferentExtraParams()
119 {
120 TestHelpers.InMethod();
121
122 string dtText = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;";
123
124 SetupScene(false);
125 SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
126
127 m_dtm.AddDynamicTextureData(
128 m_scene.RegionInfo.RegionID,
129 so.UUID,
130 m_vrm.GetContentType(),
131 dtText,
132 "",
133 0);
134
135 UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
136
137 m_dtm.AddDynamicTextureData(
138 m_scene.RegionInfo.RegionID,
139 so.UUID,
140 m_vrm.GetContentType(),
141 dtText,
142 "alpha:250",
143 0);
144
145 Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
146 }
147
148 [Test]
149 public void TestRepeatSameDrawContainingImage()
150 {
151 TestHelpers.InMethod();
152
153 string dtText
154 = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World; Image http://localhost/shouldnotexist.png";
155
156 SetupScene(false);
157 SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
158
159 m_dtm.AddDynamicTextureData(
160 m_scene.RegionInfo.RegionID,
161 so.UUID,
162 m_vrm.GetContentType(),
163 dtText,
164 "",
165 0);
166
167 UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
168
169 m_dtm.AddDynamicTextureData(
170 m_scene.RegionInfo.RegionID,
171 so.UUID,
172 m_vrm.GetContentType(),
173 dtText,
174 "",
175 0);
176
177 Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
178 }
179
180 [Test]
181 public void TestDrawReusingTexture()
182 {
183 TestHelpers.InMethod();
184
185 SetupScene(true);
186 SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
187 UUID originalTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
188
189 m_dtm.AddDynamicTextureData(
190 m_scene.RegionInfo.RegionID,
191 so.UUID,
192 m_vrm.GetContentType(),
193 "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;",
194 "",
195 0);
71 196
72 Assert.That(originalTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID)); 197 Assert.That(originalTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
73 } 198 }
199
200 [Test]
201 public void TestRepeatSameDrawReusingTexture()
202 {
203 TestHelpers.InMethod();
204
205 string dtText = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;";
206
207 SetupScene(true);
208 SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
209
210 m_dtm.AddDynamicTextureData(
211 m_scene.RegionInfo.RegionID,
212 so.UUID,
213 m_vrm.GetContentType(),
214 dtText,
215 "",
216 0);
217
218 UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
219
220 m_dtm.AddDynamicTextureData(
221 m_scene.RegionInfo.RegionID,
222 so.UUID,
223 m_vrm.GetContentType(),
224 dtText,
225 "",
226 0);
227
228 Assert.That(firstDynamicTextureID, Is.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
229 }
230
231 [Test]
232 public void TestRepeatSameDrawDifferentExtraParamsReusingTexture()
233 {
234 TestHelpers.InMethod();
235
236 string dtText = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;";
237
238 SetupScene(true);
239 SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
240
241 m_dtm.AddDynamicTextureData(
242 m_scene.RegionInfo.RegionID,
243 so.UUID,
244 m_vrm.GetContentType(),
245 dtText,
246 "",
247 0);
248
249 UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
250
251 m_dtm.AddDynamicTextureData(
252 m_scene.RegionInfo.RegionID,
253 so.UUID,
254 m_vrm.GetContentType(),
255 dtText,
256 "alpha:250",
257 0);
258
259 Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
260 }
261
262 [Test]
263 public void TestRepeatSameDrawContainingImageReusingTexture()
264 {
265 TestHelpers.InMethod();
266
267 string dtText
268 = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World; Image http://localhost/shouldnotexist.png";
269
270 SetupScene(true);
271 SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
272
273 m_dtm.AddDynamicTextureData(
274 m_scene.RegionInfo.RegionID,
275 so.UUID,
276 m_vrm.GetContentType(),
277 dtText,
278 "",
279 0);
280
281 UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
282
283 m_dtm.AddDynamicTextureData(
284 m_scene.RegionInfo.RegionID,
285 so.UUID,
286 m_vrm.GetContentType(),
287 dtText,
288 "",
289 0);
290
291 Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
292 }
74 } 293 }
75} \ No newline at end of file 294} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs
index 05eaaec..f687646 100644
--- a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs
@@ -30,6 +30,7 @@ using System.Drawing;
30using System.Drawing.Imaging; 30using System.Drawing.Imaging;
31using System.Globalization; 31using System.Globalization;
32using System.IO; 32using System.IO;
33using System.Linq;
33using System.Net; 34using System.Net;
34using Nini.Config; 35using Nini.Config;
35using OpenMetaverse; 36using OpenMetaverse;
@@ -47,7 +48,6 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
47 { 48 {
48 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 49 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
49 50
50 private string m_name = "VectorRenderModule";
51 private Scene m_scene; 51 private Scene m_scene;
52 private IDynamicTextureManager m_textureManager; 52 private IDynamicTextureManager m_textureManager;
53 private Graphics m_graph; 53 private Graphics m_graph;
@@ -61,12 +61,12 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
61 61
62 public string GetContentType() 62 public string GetContentType()
63 { 63 {
64 return ("vector"); 64 return "vector";
65 } 65 }
66 66
67 public string GetName() 67 public string GetName()
68 { 68 {
69 return m_name; 69 return Name;
70 } 70 }
71 71
72 public bool SupportsAsynchronous() 72 public bool SupportsAsynchronous()
@@ -74,14 +74,26 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
74 return true; 74 return true;
75 } 75 }
76 76
77// public bool AlwaysIdenticalConversion(string bodyData, string extraParams)
78// {
79// string[] lines = GetLines(bodyData);
80// return lines.Any((str, r) => str.StartsWith("Image"));
81// }
82
77 public byte[] ConvertUrl(string url, string extraParams) 83 public byte[] ConvertUrl(string url, string extraParams)
78 { 84 {
79 return null; 85 return null;
80 } 86 }
81 87
82 public byte[] ConvertStream(Stream data, string extraParams) 88 public byte[] ConvertData(string bodyData, string extraParams)
83 { 89 {
84 return null; 90 bool reuseable;
91 return Draw(bodyData, extraParams, out reuseable);
92 }
93
94 private byte[] ConvertData(string bodyData, string extraParams, out bool reuseable)
95 {
96 return Draw(bodyData, extraParams, out reuseable);
85 } 97 }
86 98
87 public bool AsyncConvertUrl(UUID id, string url, string extraParams) 99 public bool AsyncConvertUrl(UUID id, string url, string extraParams)
@@ -91,7 +103,12 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
91 103
92 public bool AsyncConvertData(UUID id, string bodyData, string extraParams) 104 public bool AsyncConvertData(UUID id, string bodyData, string extraParams)
93 { 105 {
94 Draw(bodyData, id, extraParams); 106 // XXX: This isn't actually being done asynchronously!
107 bool reuseable;
108 byte[] data = ConvertData(bodyData, extraParams, out reuseable);
109
110 m_textureManager.ReturnData(id, data, reuseable);
111
95 return true; 112 return true;
96 } 113 }
97 114
@@ -152,7 +169,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
152 169
153 public string Name 170 public string Name
154 { 171 {
155 get { return m_name; } 172 get { return "VectorRenderModule"; }
156 } 173 }
157 174
158 public bool IsSharedModule 175 public bool IsSharedModule
@@ -162,7 +179,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
162 179
163 #endregion 180 #endregion
164 181
165 private void Draw(string data, UUID id, string extraParams) 182 private byte[] Draw(string data, string extraParams, out bool reuseable)
166 { 183 {
167 // We need to cater for old scripts that didnt use extraParams neatly, they use either an integer size which represents both width and height, or setalpha 184 // We need to cater for old scripts that didnt use extraParams neatly, they use either an integer size which represents both width and height, or setalpha
168 // we will now support multiple comma seperated params in the form width:256,height:512,alpha:255 185 // we will now support multiple comma seperated params in the form width:256,height:512,alpha:255
@@ -343,7 +360,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
343 } 360 }
344 } 361 }
345 362
346 GDIDraw(data, graph, altDataDelim); 363 GDIDraw(data, graph, altDataDelim, out reuseable);
347 } 364 }
348 365
349 byte[] imageJ2000 = new byte[0]; 366 byte[] imageJ2000 = new byte[0];
@@ -359,7 +376,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
359 e.Message, e.StackTrace); 376 e.Message, e.StackTrace);
360 } 377 }
361 378
362 m_textureManager.ReturnData(id, imageJ2000); 379 return imageJ2000;
363 } 380 }
364 finally 381 finally
365 { 382 {
@@ -434,8 +451,21 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
434 } 451 }
435*/ 452*/
436 453
437 private void GDIDraw(string data, Graphics graph, char dataDelim) 454 /// <summary>
455 /// Split input data into discrete command lines.
456 /// </summary>
457 /// <returns></returns>
458 /// <param name='data'></param>
459 /// <param name='dataDelim'></param>
460 private string[] GetLines(string data, char dataDelim)
438 { 461 {
462 char[] lineDelimiter = { dataDelim };
463 return data.Split(lineDelimiter);
464 }
465
466 private void GDIDraw(string data, Graphics graph, char dataDelim, out bool reuseable)
467 {
468 reuseable = true;
439 Point startPoint = new Point(0, 0); 469 Point startPoint = new Point(0, 0);
440 Point endPoint = new Point(0, 0); 470 Point endPoint = new Point(0, 0);
441 Pen drawPen = null; 471 Pen drawPen = null;
@@ -450,11 +480,9 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
450 myFont = new Font(fontName, fontSize); 480 myFont = new Font(fontName, fontSize);
451 myBrush = new SolidBrush(Color.Black); 481 myBrush = new SolidBrush(Color.Black);
452 482
453 char[] lineDelimiter = {dataDelim};
454 char[] partsDelimiter = {','}; 483 char[] partsDelimiter = {','};
455 string[] lines = data.Split(lineDelimiter);
456 484
457 foreach (string line in lines) 485 foreach (string line in GetLines(data, dataDelim))
458 { 486 {
459 string nextLine = line.Trim(); 487 string nextLine = line.Trim();
460 //replace with switch, or even better, do some proper parsing 488 //replace with switch, or even better, do some proper parsing
@@ -485,6 +513,10 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
485 } 513 }
486 else if (nextLine.StartsWith("Image")) 514 else if (nextLine.StartsWith("Image"))
487 { 515 {
516 // We cannot reuse any generated texture involving fetching an image via HTTP since that image
517 // can change.
518 reuseable = false;
519
488 float x = 0; 520 float x = 0;
489 float y = 0; 521 float y = 0;
490 GetParams(partsDelimiter, ref nextLine, 5, ref x, ref y); 522 GetParams(partsDelimiter, ref nextLine, 5, ref x, ref y);
diff --git a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
index 402b9fb..d99567c 100644
--- a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
+++ b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
@@ -414,6 +414,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain
414 private void LoadPlugins() 414 private void LoadPlugins()
415 { 415 {
416 m_plugineffects = new Dictionary<string, ITerrainEffect>(); 416 m_plugineffects = new Dictionary<string, ITerrainEffect>();
417 LoadPlugins(Assembly.GetCallingAssembly());
417 string plugineffectsPath = "Terrain"; 418 string plugineffectsPath = "Terrain";
418 419
419 // Load the files in the Terrain/ dir 420 // Load the files in the Terrain/ dir
@@ -427,34 +428,39 @@ namespace OpenSim.Region.CoreModules.World.Terrain
427 try 428 try
428 { 429 {
429 Assembly library = Assembly.LoadFrom(file); 430 Assembly library = Assembly.LoadFrom(file);
430 foreach (Type pluginType in library.GetTypes()) 431 LoadPlugins(library);
431 { 432 }
432 try 433 catch (BadImageFormatException)
433 { 434 {
434 if (pluginType.IsAbstract || pluginType.IsNotPublic) 435 }
435 continue; 436 }
437 }
436 438
437 string typeName = pluginType.Name; 439 private void LoadPlugins(Assembly library)
440 {
441 foreach (Type pluginType in library.GetTypes())
442 {
443 try
444 {
445 if (pluginType.IsAbstract || pluginType.IsNotPublic)
446 continue;
438 447
439 if (pluginType.GetInterface("ITerrainEffect", false) != null) 448 string typeName = pluginType.Name;
440 {
441 ITerrainEffect terEffect = (ITerrainEffect) Activator.CreateInstance(library.GetType(pluginType.ToString()));
442 449
443 InstallPlugin(typeName, terEffect); 450 if (pluginType.GetInterface("ITerrainEffect", false) != null)
444 } 451 {
445 else if (pluginType.GetInterface("ITerrainLoader", false) != null) 452 ITerrainEffect terEffect = (ITerrainEffect)Activator.CreateInstance(library.GetType(pluginType.ToString()));
446 { 453
447 ITerrainLoader terLoader = (ITerrainLoader) Activator.CreateInstance(library.GetType(pluginType.ToString())); 454 InstallPlugin(typeName, terEffect);
448 m_loaders[terLoader.FileExtension] = terLoader; 455 }
449 m_log.Info("L ... " + typeName); 456 else if (pluginType.GetInterface("ITerrainLoader", false) != null)
450 } 457 {
451 } 458 ITerrainLoader terLoader = (ITerrainLoader)Activator.CreateInstance(library.GetType(pluginType.ToString()));
452 catch (AmbiguousMatchException) 459 m_loaders[terLoader.FileExtension] = terLoader;
453 { 460 m_log.Info("L ... " + typeName);
454 }
455 } 461 }
456 } 462 }
457 catch (BadImageFormatException) 463 catch (AmbiguousMatchException)
458 { 464 {
459 } 465 }
460 } 466 }
@@ -1178,7 +1184,8 @@ namespace OpenSim.Region.CoreModules.World.Terrain
1178 1184
1179 private void InterfaceRunPluginEffect(Object[] args) 1185 private void InterfaceRunPluginEffect(Object[] args)
1180 { 1186 {
1181 if ((string) args[0] == "list") 1187 string firstArg = (string)args[0];
1188 if (firstArg == "list")
1182 { 1189 {
1183 m_log.Info("List of loaded plugins"); 1190 m_log.Info("List of loaded plugins");
1184 foreach (KeyValuePair<string, ITerrainEffect> kvp in m_plugineffects) 1191 foreach (KeyValuePair<string, ITerrainEffect> kvp in m_plugineffects)
@@ -1187,14 +1194,14 @@ namespace OpenSim.Region.CoreModules.World.Terrain
1187 } 1194 }
1188 return; 1195 return;
1189 } 1196 }
1190 if ((string) args[0] == "reload") 1197 if (firstArg == "reload")
1191 { 1198 {
1192 LoadPlugins(); 1199 LoadPlugins();
1193 return; 1200 return;
1194 } 1201 }
1195 if (m_plugineffects.ContainsKey((string) args[0])) 1202 if (m_plugineffects.ContainsKey(firstArg))
1196 { 1203 {
1197 m_plugineffects[(string) args[0]].RunEffect(m_channel); 1204 m_plugineffects[firstArg].RunEffect(m_channel);
1198 CheckForTerrainUpdates(); 1205 CheckForTerrainUpdates();
1199 } 1206 }
1200 else 1207 else
diff --git a/OpenSim/Region/Framework/Interfaces/IDynamicTextureManager.cs b/OpenSim/Region/Framework/Interfaces/IDynamicTextureManager.cs
index 8954513..1a3bcbb 100644
--- a/OpenSim/Region/Framework/Interfaces/IDynamicTextureManager.cs
+++ b/OpenSim/Region/Framework/Interfaces/IDynamicTextureManager.cs
@@ -33,7 +33,7 @@ namespace OpenSim.Region.Framework.Interfaces
33 public interface IDynamicTextureManager 33 public interface IDynamicTextureManager
34 { 34 {
35 void RegisterRender(string handleType, IDynamicTextureRender render); 35 void RegisterRender(string handleType, IDynamicTextureRender render);
36 void ReturnData(UUID id, byte[] data); 36 void ReturnData(UUID id, byte[] data, bool isReuseable);
37 37
38 UUID AddDynamicTextureURL(UUID simID, UUID primID, string contentType, string url, string extraParams, 38 UUID AddDynamicTextureURL(UUID simID, UUID primID, string contentType, string url, string extraParams,
39 int updateTimer); 39 int updateTimer);
@@ -113,8 +113,20 @@ namespace OpenSim.Region.Framework.Interfaces
113 string GetName(); 113 string GetName();
114 string GetContentType(); 114 string GetContentType();
115 bool SupportsAsynchronous(); 115 bool SupportsAsynchronous();
116
117// /// <summary>
118// /// Return true if converting the input body and extra params data will always result in the same byte[] array
119// /// </summary>
120// /// <remarks>
121// /// This method allows the caller to use a previously generated asset if it has one.
122// /// </remarks>
123// /// <returns></returns>
124// /// <param name='bodyData'></param>
125// /// <param name='extraParams'></param>
126// bool AlwaysIdenticalConversion(string bodyData, string extraParams);
127
116 byte[] ConvertUrl(string url, string extraParams); 128 byte[] ConvertUrl(string url, string extraParams);
117 byte[] ConvertStream(Stream data, string extraParams); 129 byte[] ConvertData(string bodyData, string extraParams);
118 bool AsyncConvertUrl(UUID id, string url, string extraParams); 130 bool AsyncConvertUrl(UUID id, string url, string extraParams);
119 bool AsyncConvertData(UUID id, string bodyData, string extraParams); 131 bool AsyncConvertData(UUID id, string bodyData, string extraParams);
120 void GetDrawStringSize(string text, string fontName, int fontSize, 132 void GetDrawStringSize(string text, string fontName, int fontSize,
diff --git a/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs b/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs
index 44d2d45..9457ebb 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs
@@ -50,9 +50,41 @@ using OpenSim.Tests.Common.Mock;
50namespace OpenSim.Region.Framework.Tests 50namespace OpenSim.Region.Framework.Tests
51{ 51{
52 [TestFixture] 52 [TestFixture]
53 public class UserInventoryTests 53 public class UserInventoryTests : OpenSimTestCase
54 { 54 {
55 [Test] 55 [Test]
56 public void TestCreateInventoryFolders()
57 {
58 TestHelpers.InMethod();
59// TestHelpers.EnableLogging();
60
61 // For this test both folders will have the same name which is legal in SL user inventories.
62 string foldersName = "f1";
63
64 Scene scene = new SceneHelpers().SetupScene();
65 UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene, TestHelpers.ParseTail(1001));
66
67 UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, user1.PrincipalID, foldersName);
68
69 List<InventoryFolderBase> oneFolder
70 = UserInventoryHelpers.GetInventoryFolders(scene.InventoryService, user1.PrincipalID, foldersName);
71
72 Assert.That(oneFolder.Count, Is.EqualTo(1));
73 InventoryFolderBase firstRetrievedFolder = oneFolder[0];
74 Assert.That(firstRetrievedFolder.Name, Is.EqualTo(foldersName));
75
76 UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, user1.PrincipalID, foldersName);
77
78 List<InventoryFolderBase> twoFolders
79 = UserInventoryHelpers.GetInventoryFolders(scene.InventoryService, user1.PrincipalID, foldersName);
80
81 Assert.That(twoFolders.Count, Is.EqualTo(2));
82 Assert.That(twoFolders[0].Name, Is.EqualTo(foldersName));
83 Assert.That(twoFolders[1].Name, Is.EqualTo(foldersName));
84 Assert.That(twoFolders[0].ID, Is.Not.EqualTo(twoFolders[1].ID));
85 }
86
87 [Test]
56 public void TestGiveInventoryItem() 88 public void TestGiveInventoryItem()
57 { 89 {
58 TestHelpers.InMethod(); 90 TestHelpers.InMethod();
@@ -83,7 +115,7 @@ namespace OpenSim.Region.Framework.Tests
83 public void TestGiveInventoryFolder() 115 public void TestGiveInventoryFolder()
84 { 116 {
85 TestHelpers.InMethod(); 117 TestHelpers.InMethod();
86// log4net.Config.XmlConfigurator.Configure(); 118// TestHelpers.EnableLogging();
87 119
88 Scene scene = new SceneHelpers().SetupScene(); 120 Scene scene = new SceneHelpers().SetupScene();
89 UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene, TestHelpers.ParseTail(1001)); 121 UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene, TestHelpers.ParseTail(1001));
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 5316d08..61e8a28 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -7701,7 +7701,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7701 { 7701 {
7702 m_host.AddScriptLPS(1); 7702 m_host.AddScriptLPS(1);
7703 7703
7704 setLinkPrimParams(ScriptBaseClass.LINK_THIS, rules); 7704 setLinkPrimParams(ScriptBaseClass.LINK_THIS, rules, "llSetPrimitiveParams");
7705 7705
7706 ScriptSleep(200); 7706 ScriptSleep(200);
7707 } 7707 }
@@ -7710,10 +7710,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7710 { 7710 {
7711 m_host.AddScriptLPS(1); 7711 m_host.AddScriptLPS(1);
7712 7712
7713 setLinkPrimParams(linknumber, rules); 7713 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast");
7714
7715 ScriptSleep(200);
7714 } 7716 }
7715 7717
7716 private void setLinkPrimParams(int linknumber, LSL_List rules) 7718 private void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc)
7717 { 7719 {
7718 List<object> parts = new List<object>(); 7720 List<object> parts = new List<object>();
7719 List<SceneObjectPart> prims = GetLinkParts(linknumber); 7721 List<SceneObjectPart> prims = GetLinkParts(linknumber);
@@ -7724,15 +7726,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7724 parts.Add(p); 7726 parts.Add(p);
7725 7727
7726 LSL_List remaining = null; 7728 LSL_List remaining = null;
7729 uint rulesParsed = 0;
7727 7730
7728 if (parts.Count > 0) 7731 if (parts.Count > 0)
7729 { 7732 {
7730 foreach (object part in parts) 7733 foreach (object part in parts)
7731 { 7734 {
7732 if (part is SceneObjectPart) 7735 if (part is SceneObjectPart)
7733 remaining = SetPrimParams((SceneObjectPart)part, rules); 7736 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7734 else 7737 else
7735 remaining = SetPrimParams((ScenePresence)part, rules); 7738 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7736 } 7739 }
7737 7740
7738 while ((object)remaining != null && remaining.Length > 2) 7741 while ((object)remaining != null && remaining.Length > 2)
@@ -7750,9 +7753,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7750 foreach (object part in parts) 7753 foreach (object part in parts)
7751 { 7754 {
7752 if (part is SceneObjectPart) 7755 if (part is SceneObjectPart)
7753 remaining = SetPrimParams((SceneObjectPart)part, rules); 7756 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7754 else 7757 else
7755 remaining = SetPrimParams((ScenePresence)part, rules); 7758 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7756 } 7759 }
7757 } 7760 }
7758 } 7761 }
@@ -7790,6 +7793,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7790 7793
7791 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7794 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7792 { 7795 {
7796 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams");
7793 llSetLinkPrimitiveParamsFast(linknumber, rules); 7797 llSetLinkPrimitiveParamsFast(linknumber, rules);
7794 ScriptSleep(200); 7798 ScriptSleep(200);
7795 } 7799 }
@@ -7817,12 +7821,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7817 return new Vector3((float)x, (float)y, (float)z); 7821 return new Vector3((float)x, (float)y, (float)z);
7818 } 7822 }
7819 7823
7820 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules) 7824 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed)
7821 { 7825 {
7822 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) 7826 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7823 return null; 7827 return null;
7824 7828
7825 int idx = 0; 7829 int idx = 0;
7830 int idxStart = 0;
7826 7831
7827 SceneObjectGroup parentgrp = part.ParentGroup; 7832 SceneObjectGroup parentgrp = part.ParentGroup;
7828 7833
@@ -7833,9 +7838,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7833 { 7838 {
7834 while (idx < rules.Length) 7839 while (idx < rules.Length)
7835 { 7840 {
7841 ++rulesParsed;
7836 int code = rules.GetLSLIntegerItem(idx++); 7842 int code = rules.GetLSLIntegerItem(idx++);
7837 7843
7838 int remain = rules.Length - idx; 7844 int remain = rules.Length - idx;
7845 idxStart = idx;
7839 7846
7840 int face; 7847 int face;
7841 LSL_Vector v; 7848 LSL_Vector v;
@@ -8243,7 +8250,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8243 } 8250 }
8244 catch (InvalidCastException e) 8251 catch (InvalidCastException e)
8245 { 8252 {
8246 ShoutError(e.Message); 8253 ShoutError(string.Format(
8254 "{0} error running rule #{1}: arg #{2} ",
8255 originFunc, rulesParsed, idx - idxStart) + e.Message);
8247 } 8256 }
8248 finally 8257 finally
8249 { 8258 {
@@ -11660,7 +11669,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11660 return tid.ToString(); 11669 return tid.ToString();
11661 } 11670 }
11662 11671
11663 public void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules) 11672 public void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules, string originFunc)
11664 { 11673 {
11665 SceneObjectPart obj = World.GetSceneObjectPart(new UUID(prim)); 11674 SceneObjectPart obj = World.GetSceneObjectPart(new UUID(prim));
11666 if (obj == null) 11675 if (obj == null)
@@ -11669,14 +11678,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11669 if (obj.OwnerID != m_host.OwnerID) 11678 if (obj.OwnerID != m_host.OwnerID)
11670 return; 11679 return;
11671 11680
11672 LSL_List remaining = SetPrimParams(obj, rules); 11681 uint rulesParsed = 0;
11682 LSL_List remaining = SetPrimParams(obj, rules, originFunc, ref rulesParsed);
11673 11683
11674 while ((object)remaining != null && remaining.Length > 2) 11684 while ((object)remaining != null && remaining.Length > 2)
11675 { 11685 {
11676 LSL_Integer newLink = remaining.GetLSLIntegerItem(0); 11686 LSL_Integer newLink = remaining.GetLSLIntegerItem(0);
11677 LSL_List newrules = remaining.GetSublist(1, -1); 11687 LSL_List newrules = remaining.GetSublist(1, -1);
11678 foreach(SceneObjectPart part in GetLinkParts(obj, newLink)){ 11688 foreach(SceneObjectPart part in GetLinkParts(obj, newLink)){
11679 remaining = SetPrimParams(part, newrules); 11689 remaining = SetPrimParams(part, newrules, originFunc, ref rulesParsed);
11680 } 11690 }
11681 } 11691 }
11682 } 11692 }
@@ -12640,11 +12650,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12640 } 12650 }
12641 } 12651 }
12642 12652
12643 protected LSL_List SetPrimParams(ScenePresence av, LSL_List rules) 12653 protected LSL_List SetPrimParams(ScenePresence av, LSL_List rules, string originFunc, ref uint rulesParsed)
12644 { 12654 {
12645 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset. 12655 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
12646 12656
12647 int idx = 0; 12657 int idx = 0;
12658 int idxStart = 0;
12648 12659
12649 bool positionChanged = false; 12660 bool positionChanged = false;
12650 Vector3 finalPos = Vector3.Zero; 12661 Vector3 finalPos = Vector3.Zero;
@@ -12653,9 +12664,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12653 { 12664 {
12654 while (idx < rules.Length) 12665 while (idx < rules.Length)
12655 { 12666 {
12667 ++rulesParsed;
12656 int code = rules.GetLSLIntegerItem(idx++); 12668 int code = rules.GetLSLIntegerItem(idx++);
12657 12669
12658 int remain = rules.Length - idx; 12670 int remain = rules.Length - idx;
12671 idxStart = idx;
12659 12672
12660 switch (code) 12673 switch (code)
12661 { 12674 {
@@ -12809,7 +12822,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12809 } 12822 }
12810 } 12823 }
12811 } 12824 }
12812 12825 catch (InvalidCastException e)
12826 {
12827 ShoutError(string.Format(
12828 "{0} error running rule #{1}: arg #{2} ",
12829 originFunc, rulesParsed, idx - idxStart) + e.Message);
12830 }
12813 finally 12831 finally
12814 { 12832 {
12815 if (positionChanged) 12833 if (positionChanged)
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index 5bc78d6..ceff889 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -3036,7 +3036,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3036 m_host.AddScriptLPS(1); 3036 m_host.AddScriptLPS(1);
3037 InitLSL(); 3037 InitLSL();
3038 3038
3039 m_LSL_Api.SetPrimitiveParamsEx(prim, rules); 3039 m_LSL_Api.SetPrimitiveParamsEx(prim, rules, "osSetPrimitiveParams");
3040 } 3040 }
3041 3041
3042 /// <summary> 3042 /// <summary>
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
index e08328f..05c20f9 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
@@ -429,7 +429,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
429 LSL_Integer llGetLinkNumberOfSides(LSL_Integer link); 429 LSL_Integer llGetLinkNumberOfSides(LSL_Integer link);
430 void llSetPhysicsMaterial(int material_bits, float material_gravity_modifier, float material_restitution, float material_friction, float material_density); 430 void llSetPhysicsMaterial(int material_bits, float material_gravity_modifier, float material_restitution, float material_friction, float material_density);
431 431
432 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 432 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules, string originFunc);
433 void llSetKeyframedMotion(LSL_List frames, LSL_List options); 433 void llSetKeyframedMotion(LSL_List frames, LSL_List options);
434 LSL_List GetPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 434 LSL_List GetPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
435 } 435 }
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
index 8101da5..d0e041c 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
@@ -40,16 +40,75 @@ using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
40 40
41namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces 41namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
42{ 42{
43 /// <summary>
44 /// To permit region owners to enable the extended scripting functionality
45 /// of OSSL, without allowing malicious scripts to access potentially
46 /// troublesome functions, each OSSL function is assigned a threat level,
47 /// and access to the functions is granted or denied based on a default
48 /// threshold set in OpenSim.ini (which can be overridden for individual
49 /// functions on a case-by-case basis)
50 /// </summary>
43 public enum ThreatLevel 51 public enum ThreatLevel
44 { 52 {
53 // Not documented, presumably means permanently disabled ?
45 NoAccess = -1, 54 NoAccess = -1,
55
56 /// <summary>
57 /// Function is no threat at all. It doesn't constitute a threat to
58 /// either users or the system and has no known side effects.
59 /// </summary>
46 None = 0, 60 None = 0,
61
62 /// <summary>
63 /// Abuse of this command can cause a nuisance to the region operator,
64 /// such as log message spew.
65 /// </summary>
47 Nuisance = 1, 66 Nuisance = 1,
67
68 /// <summary>
69 /// Extreme levels of abuse of this function can cause impaired
70 /// functioning of the region, or very gullible users can be tricked
71 /// into experiencing harmless effects.
72 /// </summary>
48 VeryLow = 2, 73 VeryLow = 2,
74
75 /// <summary>
76 /// Intentional abuse can cause crashes or malfunction under certain
77 /// circumstances, which can be easily rectified; or certain users can
78 /// be tricked into certain situations in an avoidable manner.
79 /// </summary>
49 Low = 3, 80 Low = 3,
81
82 /// <summary>
83 /// Intentional abuse can cause denial of service and crashes with
84 /// potential of data or state loss; or trusting users can be tricked
85 /// into embarrassing or uncomfortable situations.
86 /// </summary>
50 Moderate = 4, 87 Moderate = 4,
88
89 /// <summary>
90 /// Casual abuse can cause impaired functionality or temporary denial
91 /// of service conditions. Intentional abuse can easily cause crashes
92 /// with potential data loss, or can be used to trick experienced and
93 /// cautious users into unwanted situations, or changes global data
94 /// permanently and without undo ability.
95 /// </summary>
51 High = 5, 96 High = 5,
97
98 /// <summary>
99 /// Even normal use may, depending on the number of instances, or
100 /// frequency of use, result in severe service impairment or crash
101 /// with loss of data, or can be used to cause unwanted or harmful
102 /// effects on users without giving the user a means to avoid it.
103 /// </summary>
52 VeryHigh = 6, 104 VeryHigh = 6,
105
106 /// <summary>
107 /// Even casual use is a danger to region stability, or function allows
108 /// console or OS command execution, or function allows taking money
109 /// without consent, or allows deletion or modification of user data,
110 /// or allows the compromise of sensitive data by design.
111 /// </summary>
53 Severe = 7 112 Severe = 7
54 }; 113 };
55 114