Merge branch 'master' of /home/opensim/var/repo/opensim
						commit
						48ebea163b
					
				|  | @ -30,6 +30,10 @@ bin/*.db-journal | |||
| bin/addin-db-* | ||||
| bin/*.dll | ||||
| bin/OpenSim.vshost.exe.config | ||||
| bin/OpenSim.32BitLaunch.vshost.exe.config | ||||
| bin/OpenSim.32BitLaunch.log | ||||
| UpgradeLog.XML | ||||
| _UpgradeReport_Files/ | ||||
| bin/ScriptEngines/*-*-*-*-* | ||||
| bin/ScriptEngines/*.dll | ||||
| bin/ScriptEngines/*/*.dll | ||||
|  |  | |||
|  | @ -135,14 +135,25 @@ | |||
|   <delete dir="%temp%"/> | ||||
| </target> | ||||
| 
 | ||||
| <target name="torture" depends="build, find-nunit"> | ||||
| <target name="test-stress" depends="build, find-nunit"> | ||||
|   <setenv name="MONO_THREADS_PER_CPU" value="100" /> | ||||
| 
 | ||||
|   <exec program="${nunitcmd}" failonerror="true" resultproperty="testresult.opensim.tests.torture"> | ||||
|     <arg value="./bin/OpenSim.Tests.Torture.dll" /> | ||||
|   <exec program="${nunitcmd}" failonerror="true" resultproperty="testresult.opensim.tests.stress"> | ||||
|     <arg value="./bin/OpenSim.Tests.Stress.dll" /> | ||||
|   </exec> | ||||
| 
 | ||||
|   <fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.tests.torture)==0}" />  | ||||
|   <fail message="Failures reported in stress tests." unless="${int::parse(testresult.opensim.tests.stress)==0}" />  | ||||
|   <delete dir="%temp%"/> | ||||
| </target> | ||||
| 
 | ||||
| <target name="test-perf" depends="build, find-nunit"> | ||||
|   <setenv name="MONO_THREADS_PER_CPU" value="100" /> | ||||
| 
 | ||||
|   <exec program="${nunitcmd}" failonerror="true" resultproperty="testresult.opensim.tests.performance"> | ||||
|     <arg value="./bin/OpenSim.Tests.Performance.dll" /> | ||||
|   </exec> | ||||
| 
 | ||||
|   <fail message="Failures reported in performance tests." unless="${int::parse(testresult.opensim.tests.performance)==0}" />  | ||||
|   <delete dir="%temp%"/> | ||||
| </target> | ||||
| 
 | ||||
|  |  | |||
|  | @ -40,6 +40,11 @@ namespace OpenSim.Data | |||
|         public UUID folderID; | ||||
|         public UUID agentID; | ||||
|         public UUID parentFolderID; | ||||
| 
 | ||||
|         public XInventoryFolder Clone() | ||||
|         { | ||||
|             return (XInventoryFolder)MemberwiseClone(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public class XInventoryItem | ||||
|  | @ -64,6 +69,11 @@ namespace OpenSim.Data | |||
|         public UUID avatarID; | ||||
|         public UUID parentFolderID; | ||||
|         public int inventoryGroupPermissions; | ||||
| 
 | ||||
|         public XInventoryItem Clone() | ||||
|         { | ||||
|             return (XInventoryItem)MemberwiseClone(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public interface IXInventoryData | ||||
|  |  | |||
|  | @ -73,33 +73,27 @@ namespace OpenSim.Framework | |||
|         { | ||||
|         } | ||||
| 
 | ||||
|         public InventoryFolderBase(UUID id) | ||||
|         public InventoryFolderBase(UUID id) : this() | ||||
|         { | ||||
|             ID = id; | ||||
|         } | ||||
| 
 | ||||
|         public InventoryFolderBase(UUID id, UUID owner) | ||||
|         public InventoryFolderBase(UUID id, UUID owner) : this(id) | ||||
|         { | ||||
|             ID = id; | ||||
|             Owner = owner; | ||||
|         } | ||||
| 
 | ||||
|         public InventoryFolderBase(UUID id, string name, UUID owner, UUID parent) | ||||
|         public InventoryFolderBase(UUID id, string name, UUID owner, UUID parent) : this(id, owner) | ||||
|         { | ||||
|             ID = id; | ||||
|             Name = name; | ||||
|             Owner = owner; | ||||
|             ParentID = parent; | ||||
|         } | ||||
| 
 | ||||
|         public InventoryFolderBase(UUID id, string name, UUID owner, short type, UUID parent, ushort version) | ||||
|         public InventoryFolderBase( | ||||
|             UUID id, string name, UUID owner, short type, UUID parent, ushort version) : this(id, name, owner, parent) | ||||
|         { | ||||
|             ID = id; | ||||
|             Name = name; | ||||
|             Owner = owner; | ||||
|             Type = type; | ||||
|             ParentID = parent; | ||||
|             Version = version; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| } | ||||
|  | @ -65,9 +65,14 @@ namespace OpenSim.Framework.Serialization | |||
| 
 | ||||
|             UserAccount account = userService.GetUserAccount(UUID.Zero, userId); | ||||
|             if (account != null) | ||||
|             { | ||||
|                 return MakeOspa(account.FirstName, account.LastName); | ||||
|             } | ||||
| //            else | ||||
| //            { | ||||
| //                m_log.WarnFormat("[OSP RESOLVER]: No user account for {0}", userId); | ||||
| //                System.Console.WriteLine("[OSP RESOLVER]: No user account for {0}", userId); | ||||
| //            } | ||||
| 
 | ||||
|             return null; | ||||
|         } | ||||
|  | @ -79,10 +84,13 @@ namespace OpenSim.Framework.Serialization | |||
|         /// <returns></returns> | ||||
|         public static string MakeOspa(string firstName, string lastName) | ||||
|         { | ||||
| //            m_log.DebugFormat("[OSP RESOLVER]: Making OSPA for {0} {1}", firstName, lastName); | ||||
|             string ospa | ||||
|                 = OSPA_PREFIX + OSPA_NAME_KEY + OSPA_PAIR_SEPARATOR + firstName + OSPA_NAME_VALUE_SEPARATOR + lastName; | ||||
| 
 | ||||
| //            m_log.DebugFormat("[OSP RESOLVER]: Made OSPA {0} for {1} {2}", ospa, firstName, lastName); | ||||
| //            System.Console.WriteLine("[OSP RESOLVER]: Made OSPA {0} for {1} {2}", ospa, firstName, lastName); | ||||
|              | ||||
|             return  | ||||
|                 OSPA_PREFIX + OSPA_NAME_KEY + OSPA_PAIR_SEPARATOR + firstName + OSPA_NAME_VALUE_SEPARATOR + lastName; | ||||
|             return ospa; | ||||
|         } | ||||
|          | ||||
|         /// <summary> | ||||
|  |  | |||
|  | @ -350,38 +350,38 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
|             Assert.That(sog1.RootPart.CreatorID, Is.EqualTo(m_uaLL1.PrincipalID));             | ||||
|         } | ||||
|          | ||||
|         /// <summary> | ||||
|         /// Test loading a V0.1 OpenSim Inventory Archive (subject to change since there is no fixed format yet) where | ||||
|         /// an account exists with the same name as the creator, though not the same id. | ||||
|         /// </summary> | ||||
|         [Test] | ||||
|         public void TestLoadIarV0_1SameNameCreator() | ||||
|         { | ||||
|             TestHelpers.InMethod(); | ||||
| //            log4net.Config.XmlConfigurator.Configure(); | ||||
| 
 | ||||
|             UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaMT, "meowfood"); | ||||
|             UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaLL2, "hampshire"); | ||||
|              | ||||
|             m_archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "/", "meowfood", m_iarStream);             | ||||
|             InventoryItemBase foundItem1 | ||||
|                 = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, m_uaMT.PrincipalID, m_item1Name); | ||||
| 
 | ||||
|             Assert.That( | ||||
|                 foundItem1.CreatorId, Is.EqualTo(m_uaLL2.PrincipalID.ToString()),  | ||||
|                 "Loaded item non-uuid creator doesn't match original");             | ||||
|             Assert.That( | ||||
|                 foundItem1.CreatorIdAsUuid, Is.EqualTo(m_uaLL2.PrincipalID),  | ||||
|                 "Loaded item uuid creator doesn't match original"); | ||||
|             Assert.That(foundItem1.Owner, Is.EqualTo(m_uaMT.PrincipalID), | ||||
|                 "Loaded item owner doesn't match inventory reciever"); | ||||
|              | ||||
|             AssetBase asset1 = m_scene.AssetService.Get(foundItem1.AssetID.ToString());             | ||||
|             string xmlData = Utils.BytesToString(asset1.Data); | ||||
|             SceneObjectGroup sog1 = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); | ||||
|              | ||||
|             Assert.That(sog1.RootPart.CreatorID, Is.EqualTo(m_uaLL2.PrincipalID)); | ||||
|         } | ||||
| //        /// <summary> | ||||
| //        /// Test loading a V0.1 OpenSim Inventory Archive (subject to change since there is no fixed format yet) where | ||||
| //        /// an account exists with the same name as the creator, though not the same id. | ||||
| //        /// </summary> | ||||
| //        [Test] | ||||
| //        public void TestLoadIarV0_1SameNameCreator() | ||||
| //        { | ||||
| //            TestHelpers.InMethod(); | ||||
| //            TestHelpers.EnableLogging(); | ||||
| // | ||||
| //            UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaMT, "meowfood"); | ||||
| //            UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaLL2, "hampshire"); | ||||
| //             | ||||
| //            m_archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "/", "meowfood", m_iarStream);             | ||||
| //            InventoryItemBase foundItem1 | ||||
| //                = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, m_uaMT.PrincipalID, m_item1Name); | ||||
| // | ||||
| //            Assert.That( | ||||
| //                foundItem1.CreatorId, Is.EqualTo(m_uaLL2.PrincipalID.ToString()),  | ||||
| //                "Loaded item non-uuid creator doesn't match original");             | ||||
| //            Assert.That( | ||||
| //                foundItem1.CreatorIdAsUuid, Is.EqualTo(m_uaLL2.PrincipalID),  | ||||
| //                "Loaded item uuid creator doesn't match original"); | ||||
| //            Assert.That(foundItem1.Owner, Is.EqualTo(m_uaMT.PrincipalID), | ||||
| //                "Loaded item owner doesn't match inventory reciever"); | ||||
| //             | ||||
| //            AssetBase asset1 = m_scene.AssetService.Get(foundItem1.AssetID.ToString());             | ||||
| //            string xmlData = Utils.BytesToString(asset1.Data); | ||||
| //            SceneObjectGroup sog1 = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); | ||||
| //             | ||||
| //            Assert.That(sog1.RootPart.CreatorID, Is.EqualTo(m_uaLL2.PrincipalID)); | ||||
| //        } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Test loading a V0.1 OpenSim Inventory Archive (subject to change since there is no fixed format yet) where | ||||
|  |  | |||
|  | @ -49,6 +49,11 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture | |||
|         public const int DISP_EXPIRE = 1; | ||||
|         public const int DISP_TEMP   = 2; | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// If true then where possible dynamic textures are reused. | ||||
|         /// </summary> | ||||
|         public bool ReuseTextures { get; set; } | ||||
| 
 | ||||
|         private Dictionary<UUID, Scene> RegisteredScenes = new Dictionary<UUID, Scene>(); | ||||
| 
 | ||||
|         private Dictionary<string, IDynamicTextureRender> RenderPlugins = | ||||
|  | @ -56,6 +61,15 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture | |||
| 
 | ||||
|         private Dictionary<UUID, DynamicTextureUpdater> Updaters = new Dictionary<UUID, DynamicTextureUpdater>(); | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Record dynamic textures that we can reuse for a given data and parameter combination rather than | ||||
|         /// regenerate. | ||||
|         /// </summary> | ||||
|         /// <remarks> | ||||
|         /// Key is string.Format("{0}{1}", data | ||||
|         /// </remarks> | ||||
|         private Cache m_reuseableDynamicTextures; | ||||
| 
 | ||||
|         #region IDynamicTextureManager Members | ||||
| 
 | ||||
|         public void RegisterRender(string handleType, IDynamicTextureRender render) | ||||
|  | @ -71,7 +85,8 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture | |||
|         /// </summary> | ||||
|         /// <param name="id"></param> | ||||
|         /// <param name="data"></param> | ||||
|         public void ReturnData(UUID id, byte[] data) | ||||
|         /// <param name="isReuseable">True if the data generated can be reused for subsequent identical requests</param> | ||||
|         public void ReturnData(UUID id, byte[] data, bool isReuseable) | ||||
|         { | ||||
|             DynamicTextureUpdater updater = null; | ||||
| 
 | ||||
|  | @ -88,7 +103,11 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture | |||
|                 if (RegisteredScenes.ContainsKey(updater.SimUUID)) | ||||
|                 { | ||||
|                     Scene scene = RegisteredScenes[updater.SimUUID]; | ||||
|                     updater.DataReceived(data, scene); | ||||
|                     UUID newTextureID = updater.DataReceived(data, scene); | ||||
| 
 | ||||
|                     if (ReuseTextures && isReuseable && !updater.BlendWithOldTexture) | ||||
|                         m_reuseableDynamicTextures.Store( | ||||
|                             GenerateReusableTextureKey(updater.BodyData, updater.Params), newTextureID); | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|  | @ -169,6 +188,11 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture | |||
|         { | ||||
|             if (RenderPlugins.ContainsKey(contentType)) | ||||
|             { | ||||
|                 // If we want to reuse dynamic textures then we have to ignore any request from the caller to expire | ||||
|                 // them. | ||||
|                 if (ReuseTextures) | ||||
|                     disp = disp & ~DISP_EXPIRE; | ||||
| 
 | ||||
|                 DynamicTextureUpdater updater = new DynamicTextureUpdater(); | ||||
|                 updater.SimUUID = simID; | ||||
|                 updater.PrimID = primID; | ||||
|  | @ -183,21 +207,49 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture | |||
|                 updater.Url = "Local image"; | ||||
|                 updater.Disp = disp; | ||||
| 
 | ||||
|                 lock (Updaters) | ||||
|                 object reusableTextureUUID = null; | ||||
| 
 | ||||
|                 if (ReuseTextures) | ||||
|                     reusableTextureUUID | ||||
|                         = m_reuseableDynamicTextures.Get(GenerateReusableTextureKey(data, extraParams)); | ||||
| 
 | ||||
|                 // We cannot reuse a dynamic texture if the data is going to be blended with something already there. | ||||
|                 if (reusableTextureUUID == null || updater.BlendWithOldTexture) | ||||
|                 { | ||||
|                     if (!Updaters.ContainsKey(updater.UpdaterID)) | ||||
|                     lock (Updaters) | ||||
|                     { | ||||
|                         Updaters.Add(updater.UpdaterID, updater); | ||||
|                         if (!Updaters.ContainsKey(updater.UpdaterID)) | ||||
|                         { | ||||
|                             Updaters.Add(updater.UpdaterID, updater); | ||||
|                         } | ||||
|                     } | ||||
| 
 | ||||
|                     RenderPlugins[contentType].AsyncConvertData(updater.UpdaterID, data, extraParams); | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     // No need to add to updaters as the texture is always the same.  Not that this functionality | ||||
|                     // apppears to be implemented anyway. | ||||
|                     if (RegisteredScenes.ContainsKey(updater.SimUUID)) | ||||
|                     { | ||||
|                         SceneObjectPart part = RegisteredScenes[updater.SimUUID].GetSceneObjectPart(updater.PrimID); | ||||
| 
 | ||||
|                         if (part != null) | ||||
|                             updater.UpdatePart(part, (UUID)reusableTextureUUID); | ||||
|                     } | ||||
|                 } | ||||
| 
 | ||||
|                 RenderPlugins[contentType].AsyncConvertData(updater.UpdaterID, data, extraParams); | ||||
|                 return updater.UpdaterID; | ||||
|             } | ||||
|              | ||||
|             return UUID.Zero; | ||||
|         } | ||||
| 
 | ||||
|         private string GenerateReusableTextureKey(string data, string extraParams) | ||||
|         { | ||||
|             return string.Format("{0}{1}", data, extraParams); | ||||
|         } | ||||
| 
 | ||||
|         public void GetDrawStringSize(string contentType, string text, string fontName, int fontSize, | ||||
|                                       out double xSize, out double ySize) | ||||
|         { | ||||
|  | @ -224,6 +276,12 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture | |||
| 
 | ||||
|         public void PostInitialise() | ||||
|         { | ||||
| //            ReuseTextures = true; | ||||
|             if (ReuseTextures) | ||||
|             { | ||||
|                 m_reuseableDynamicTextures = new Cache(CacheMedium.Memory, CacheStrategy.Conservative); | ||||
|                 m_reuseableDynamicTextures.DefaultTTL = new TimeSpan(24, 0, 0); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public void Close() | ||||
|  | @ -268,10 +326,61 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture | |||
|                 BodyData = null; | ||||
|             } | ||||
| 
 | ||||
|             /// <summary> | ||||
|             /// Update the given part with the new texture. | ||||
|             /// </summary> | ||||
|             /// <returns> | ||||
|             /// The old texture UUID. | ||||
|             /// </returns> | ||||
|             public UUID UpdatePart(SceneObjectPart part, UUID textureID) | ||||
|             { | ||||
|                 UUID oldID; | ||||
| 
 | ||||
|                 lock (part) | ||||
|                 { | ||||
|                     // mostly keep the values from before | ||||
|                     Primitive.TextureEntry tmptex = part.Shape.Textures; | ||||
| 
 | ||||
|                     // FIXME: Need to return the appropriate ID if only a single face is replaced. | ||||
|                     oldID = tmptex.DefaultTexture.TextureID; | ||||
| 
 | ||||
|                     if (Face == ALL_SIDES) | ||||
|                     { | ||||
|                         oldID = tmptex.DefaultTexture.TextureID; | ||||
|                         tmptex.DefaultTexture.TextureID = textureID; | ||||
|                     } | ||||
|                     else | ||||
|                     { | ||||
|                         try | ||||
|                         { | ||||
|                             Primitive.TextureEntryFace texface = tmptex.CreateFace((uint)Face); | ||||
|                             texface.TextureID = textureID; | ||||
|                             tmptex.FaceTextures[Face] = texface; | ||||
|                         } | ||||
|                         catch (Exception) | ||||
|                         { | ||||
|                             tmptex.DefaultTexture.TextureID = textureID; | ||||
|                         } | ||||
|                     } | ||||
| 
 | ||||
|                     // I'm pretty sure we always want to force this to true | ||||
|                     // I'm pretty sure noone whats to set fullbright true if it wasn't true before. | ||||
|                     // tmptex.DefaultTexture.Fullbright = true; | ||||
| 
 | ||||
|                     part.UpdateTextureEntry(tmptex.GetBytes()); | ||||
|                 } | ||||
| 
 | ||||
|                 return oldID; | ||||
|             } | ||||
| 
 | ||||
|             /// <summary> | ||||
|             /// Called once new texture data has been received for this updater. | ||||
|             /// </summary> | ||||
|             public void DataReceived(byte[] data, Scene scene) | ||||
|             /// <param name="data"></param> | ||||
|             /// <param name="scene"></param> | ||||
|             /// <param name="isReuseable">True if the data given is reuseable.</param> | ||||
|             /// <returns>The asset UUID given to the incoming data.</returns> | ||||
|             public UUID DataReceived(byte[] data, Scene scene) | ||||
|             { | ||||
|                 SceneObjectPart part = scene.GetSceneObjectPart(PrimID); | ||||
| 
 | ||||
|  | @ -281,7 +390,8 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture | |||
|                         String.Format("DynamicTextureModule: Error preparing image using URL {0}", Url); | ||||
|                     scene.SimChat(Utils.StringToBytes(msg), ChatTypeEnum.Say, | ||||
|                                   0, part.ParentGroup.RootPart.AbsolutePosition, part.Name, part.UUID, false); | ||||
|                     return; | ||||
|                      | ||||
|                     return UUID.Zero; | ||||
|                 } | ||||
| 
 | ||||
|                 byte[] assetData = null; | ||||
|  | @ -323,52 +433,23 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture | |||
|                     cacheLayerDecode = null; | ||||
|                 } | ||||
| 
 | ||||
|                 UUID oldID = UUID.Zero; | ||||
| 
 | ||||
|                 lock (part) | ||||
|                 { | ||||
|                     // mostly keep the values from before | ||||
|                     Primitive.TextureEntry tmptex = part.Shape.Textures; | ||||
| 
 | ||||
|                     // remove the old asset from the cache | ||||
|                     oldID = tmptex.DefaultTexture.TextureID; | ||||
|                      | ||||
|                     if (Face == ALL_SIDES) | ||||
|                     { | ||||
|                         tmptex.DefaultTexture.TextureID = asset.FullID; | ||||
|                     } | ||||
|                     else | ||||
|                     { | ||||
|                         try | ||||
|                         { | ||||
|                             Primitive.TextureEntryFace texface = tmptex.CreateFace((uint)Face); | ||||
|                             texface.TextureID = asset.FullID; | ||||
|                             tmptex.FaceTextures[Face] = texface; | ||||
|                         } | ||||
|                         catch (Exception) | ||||
|                         { | ||||
|                             tmptex.DefaultTexture.TextureID = asset.FullID; | ||||
|                         } | ||||
|                     } | ||||
| 
 | ||||
|                     // I'm pretty sure we always want to force this to true | ||||
|                     // I'm pretty sure noone whats to set fullbright true if it wasn't true before. | ||||
|                     // tmptex.DefaultTexture.Fullbright = true; | ||||
| 
 | ||||
|                     part.UpdateTextureEntry(tmptex.GetBytes()); | ||||
|                 } | ||||
|                 UUID oldID = UpdatePart(part, asset.FullID); | ||||
| 
 | ||||
|                 if (oldID != UUID.Zero && ((Disp & DISP_EXPIRE) != 0)) | ||||
|                 { | ||||
|                     if (oldAsset == null) oldAsset = scene.AssetService.Get(oldID.ToString()); | ||||
|                     if (oldAsset == null) | ||||
|                         oldAsset = scene.AssetService.Get(oldID.ToString()); | ||||
| 
 | ||||
|                     if (oldAsset != null) | ||||
|                     { | ||||
|                         if (oldAsset.Temporary == true) | ||||
|                         if (oldAsset.Temporary) | ||||
|                         { | ||||
|                             scene.AssetService.Delete(oldID.ToString()); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
| 
 | ||||
|                 return asset.FullID; | ||||
|             } | ||||
| 
 | ||||
|             private byte[] BlendTextures(byte[] frontImage, byte[] backImage, bool setNewAlpha, byte newAlpha) | ||||
|  |  | |||
|  | @ -84,6 +84,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp | |||
|         public string body; | ||||
|         public int responseCode; | ||||
|         public string responseBody; | ||||
|         public string responseType = "text/plain"; | ||||
|         //public ManualResetEvent ev; | ||||
|         public bool requestDone; | ||||
|         public int startTime; | ||||
|  | @ -302,6 +303,22 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp | |||
|             } | ||||
|         } | ||||
|          | ||||
|         public void HttpContentType(UUID request, string type) | ||||
|         { | ||||
|             lock (m_UrlMap) | ||||
|             { | ||||
|                 if (m_RequestMap.ContainsKey(request)) | ||||
|                 { | ||||
|                     UrlData urlData = m_RequestMap[request]; | ||||
|                     urlData.requests[request].responseType = type; | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     m_log.Info("[HttpRequestHandler] There is no http-in request with id " + request.ToString()); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|          | ||||
|         public void HttpResponse(UUID request, int status, string body) | ||||
|         { | ||||
|             lock (m_UrlMap) | ||||
|  | @ -504,7 +521,8 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp | |||
|                 //put response | ||||
|                 response["int_response_code"] = requestData.responseCode; | ||||
|                 response["str_response_string"] = requestData.responseBody; | ||||
|                 response["content_type"] = "text/plain"; | ||||
|                 response["content_type"] = requestData.responseType; | ||||
|                 // response["content_type"] = "text/plain"; | ||||
|                 response["keepalive"] = false; | ||||
|                 response["reusecontext"] = false; | ||||
| 
 | ||||
|  |  | |||
|  | @ -67,12 +67,18 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL | |||
|             return true; | ||||
|         } | ||||
| 
 | ||||
| //        public bool AlwaysIdenticalConversion(string bodyData, string extraParams) | ||||
| //        { | ||||
| //            // We don't support conversion of body data. | ||||
| //            return false; | ||||
| //        } | ||||
| 
 | ||||
|         public byte[] ConvertUrl(string url, string extraParams) | ||||
|         { | ||||
|             return null; | ||||
|         } | ||||
| 
 | ||||
|         public byte[] ConvertStream(Stream data, string extraParams) | ||||
|         public byte[] ConvertData(string bodyData, string extraParams) | ||||
|         { | ||||
|             return null; | ||||
|         } | ||||
|  | @ -236,9 +242,11 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL | |||
|                     stream.Close(); | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             m_log.DebugFormat("[LOADIMAGEURLMODULE] Returning {0} bytes of image data for request {1}", | ||||
|                                        imageJ2000.Length, state.RequestID); | ||||
|             m_textureManager.ReturnData(state.RequestID, imageJ2000); | ||||
| 
 | ||||
|             m_textureManager.ReturnData(state.RequestID, imageJ2000, false); | ||||
|         } | ||||
| 
 | ||||
|         #region Nested type: RequestState | ||||
|  |  | |||
|  | @ -45,31 +45,250 @@ using OpenSim.Tests.Common.Mock; | |||
| namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests | ||||
| { | ||||
|     [TestFixture] | ||||
|     public class VectorRenderModuleTests | ||||
|     public class VectorRenderModuleTests : OpenSimTestCase | ||||
|     { | ||||
|         Scene m_scene; | ||||
|         DynamicTextureModule m_dtm; | ||||
|         VectorRenderModule m_vrm; | ||||
| 
 | ||||
|         private void SetupScene(bool reuseTextures) | ||||
|         { | ||||
|             m_scene = new SceneHelpers().SetupScene(); | ||||
| 
 | ||||
|             m_dtm = new DynamicTextureModule(); | ||||
|             m_dtm.ReuseTextures = reuseTextures; | ||||
| 
 | ||||
|             m_vrm = new VectorRenderModule(); | ||||
| 
 | ||||
|             SceneHelpers.SetupSceneModules(m_scene, m_dtm, m_vrm); | ||||
|         } | ||||
| 
 | ||||
|         [Test] | ||||
|         public void TestDraw() | ||||
|         { | ||||
|             TestHelpers.InMethod(); | ||||
| 
 | ||||
|             Scene scene = new SceneHelpers().SetupScene(); | ||||
|             DynamicTextureModule dtm = new DynamicTextureModule(); | ||||
|             VectorRenderModule vrm = new VectorRenderModule(); | ||||
|             SceneHelpers.SetupSceneModules(scene, dtm, vrm); | ||||
| 
 | ||||
|             SceneObjectGroup so = SceneHelpers.AddSceneObject(scene); | ||||
|             SetupScene(false); | ||||
|             SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene); | ||||
|             UUID originalTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID; | ||||
| 
 | ||||
|             dtm.AddDynamicTextureData( | ||||
|                 scene.RegionInfo.RegionID, | ||||
|             m_dtm.AddDynamicTextureData( | ||||
|                 m_scene.RegionInfo.RegionID, | ||||
|                 so.UUID, | ||||
|                 vrm.GetContentType(), | ||||
|                 m_vrm.GetContentType(), | ||||
|                 "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;", | ||||
|                 "", | ||||
|                 0); | ||||
| 
 | ||||
|             Assert.That(originalTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID)); | ||||
|         } | ||||
| 
 | ||||
|         [Test] | ||||
|         public void TestRepeatSameDraw() | ||||
|         { | ||||
|             TestHelpers.InMethod(); | ||||
| 
 | ||||
|             string dtText = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;"; | ||||
| 
 | ||||
|             SetupScene(false); | ||||
|             SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene); | ||||
| 
 | ||||
|             m_dtm.AddDynamicTextureData( | ||||
|                 m_scene.RegionInfo.RegionID, | ||||
|                 so.UUID, | ||||
|                 m_vrm.GetContentType(), | ||||
|                 dtText, | ||||
|                 "", | ||||
|                 0); | ||||
| 
 | ||||
|             UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID; | ||||
| 
 | ||||
|             m_dtm.AddDynamicTextureData( | ||||
|                 m_scene.RegionInfo.RegionID, | ||||
|                 so.UUID, | ||||
|                 m_vrm.GetContentType(), | ||||
|                 dtText, | ||||
|                 "", | ||||
|                 0); | ||||
| 
 | ||||
|             Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID)); | ||||
|         } | ||||
| 
 | ||||
|         [Test] | ||||
|         public void TestRepeatSameDrawDifferentExtraParams() | ||||
|         { | ||||
|             TestHelpers.InMethod(); | ||||
| 
 | ||||
|             string dtText = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;"; | ||||
| 
 | ||||
|             SetupScene(false); | ||||
|             SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene); | ||||
| 
 | ||||
|             m_dtm.AddDynamicTextureData( | ||||
|                 m_scene.RegionInfo.RegionID, | ||||
|                 so.UUID, | ||||
|                 m_vrm.GetContentType(), | ||||
|                 dtText, | ||||
|                 "", | ||||
|                 0); | ||||
| 
 | ||||
|             UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID; | ||||
| 
 | ||||
|             m_dtm.AddDynamicTextureData( | ||||
|                 m_scene.RegionInfo.RegionID, | ||||
|                 so.UUID, | ||||
|                 m_vrm.GetContentType(), | ||||
|                 dtText, | ||||
|                 "alpha:250", | ||||
|                 0); | ||||
| 
 | ||||
|             Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID)); | ||||
|         } | ||||
| 
 | ||||
|         [Test] | ||||
|         public void TestRepeatSameDrawContainingImage() | ||||
|         { | ||||
|             TestHelpers.InMethod(); | ||||
| 
 | ||||
|             string dtText | ||||
|                 = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World; Image http://localhost/shouldnotexist.png"; | ||||
| 
 | ||||
|             SetupScene(false); | ||||
|             SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene); | ||||
| 
 | ||||
|             m_dtm.AddDynamicTextureData( | ||||
|                 m_scene.RegionInfo.RegionID, | ||||
|                 so.UUID, | ||||
|                 m_vrm.GetContentType(), | ||||
|                 dtText, | ||||
|                 "", | ||||
|                 0); | ||||
| 
 | ||||
|             UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID; | ||||
| 
 | ||||
|             m_dtm.AddDynamicTextureData( | ||||
|                 m_scene.RegionInfo.RegionID, | ||||
|                 so.UUID, | ||||
|                 m_vrm.GetContentType(), | ||||
|                 dtText, | ||||
|                 "", | ||||
|                 0); | ||||
| 
 | ||||
|             Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID)); | ||||
|         } | ||||
| 
 | ||||
|         [Test] | ||||
|         public void TestDrawReusingTexture() | ||||
|         { | ||||
|             TestHelpers.InMethod(); | ||||
| 
 | ||||
|             SetupScene(true); | ||||
|             SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene); | ||||
|             UUID originalTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID; | ||||
| 
 | ||||
|             m_dtm.AddDynamicTextureData( | ||||
|                 m_scene.RegionInfo.RegionID, | ||||
|                 so.UUID, | ||||
|                 m_vrm.GetContentType(), | ||||
|                 "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;", | ||||
|                 "", | ||||
|                 0); | ||||
| 
 | ||||
|             Assert.That(originalTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID)); | ||||
|         } | ||||
| 
 | ||||
|         [Test] | ||||
|         public void TestRepeatSameDrawReusingTexture() | ||||
|         { | ||||
|             TestHelpers.InMethod(); | ||||
| 
 | ||||
|             string dtText = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;"; | ||||
| 
 | ||||
|             SetupScene(true); | ||||
|             SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene); | ||||
| 
 | ||||
|             m_dtm.AddDynamicTextureData( | ||||
|                 m_scene.RegionInfo.RegionID, | ||||
|                 so.UUID, | ||||
|                 m_vrm.GetContentType(), | ||||
|                 dtText, | ||||
|                 "", | ||||
|                 0); | ||||
| 
 | ||||
|             UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID; | ||||
| 
 | ||||
|             m_dtm.AddDynamicTextureData( | ||||
|                 m_scene.RegionInfo.RegionID, | ||||
|                 so.UUID, | ||||
|                 m_vrm.GetContentType(), | ||||
|                 dtText, | ||||
|                 "", | ||||
|                 0); | ||||
| 
 | ||||
|             Assert.That(firstDynamicTextureID, Is.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID)); | ||||
|         } | ||||
| 
 | ||||
|         [Test] | ||||
|         public void TestRepeatSameDrawDifferentExtraParamsReusingTexture() | ||||
|         { | ||||
|             TestHelpers.InMethod(); | ||||
| 
 | ||||
|             string dtText = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;"; | ||||
| 
 | ||||
|             SetupScene(true); | ||||
|             SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene); | ||||
| 
 | ||||
|             m_dtm.AddDynamicTextureData( | ||||
|                 m_scene.RegionInfo.RegionID, | ||||
|                 so.UUID, | ||||
|                 m_vrm.GetContentType(), | ||||
|                 dtText, | ||||
|                 "", | ||||
|                 0); | ||||
| 
 | ||||
|             UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID; | ||||
| 
 | ||||
|             m_dtm.AddDynamicTextureData( | ||||
|                 m_scene.RegionInfo.RegionID, | ||||
|                 so.UUID, | ||||
|                 m_vrm.GetContentType(), | ||||
|                 dtText, | ||||
|                 "alpha:250", | ||||
|                 0); | ||||
| 
 | ||||
|             Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID)); | ||||
|         } | ||||
| 
 | ||||
|         [Test] | ||||
|         public void TestRepeatSameDrawContainingImageReusingTexture() | ||||
|         { | ||||
|             TestHelpers.InMethod(); | ||||
| 
 | ||||
|             string dtText | ||||
|                 = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World; Image http://localhost/shouldnotexist.png"; | ||||
| 
 | ||||
|             SetupScene(true); | ||||
|             SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene); | ||||
| 
 | ||||
|             m_dtm.AddDynamicTextureData( | ||||
|                 m_scene.RegionInfo.RegionID, | ||||
|                 so.UUID, | ||||
|                 m_vrm.GetContentType(), | ||||
|                 dtText, | ||||
|                 "", | ||||
|                 0); | ||||
| 
 | ||||
|             UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID; | ||||
| 
 | ||||
|             m_dtm.AddDynamicTextureData( | ||||
|                 m_scene.RegionInfo.RegionID, | ||||
|                 so.UUID, | ||||
|                 m_vrm.GetContentType(), | ||||
|                 dtText, | ||||
|                 "", | ||||
|                 0); | ||||
| 
 | ||||
|             Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID)); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -30,6 +30,7 @@ using System.Drawing; | |||
| using System.Drawing.Imaging; | ||||
| using System.Globalization; | ||||
| using System.IO; | ||||
| using System.Linq; | ||||
| using System.Net; | ||||
| using Nini.Config; | ||||
| using OpenMetaverse; | ||||
|  | @ -47,7 +48,6 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender | |||
|     { | ||||
|         private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||||
| 
 | ||||
|         private string m_name = "VectorRenderModule"; | ||||
|         private Scene m_scene; | ||||
|         private IDynamicTextureManager m_textureManager; | ||||
|         private Graphics m_graph; | ||||
|  | @ -61,12 +61,12 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender | |||
| 
 | ||||
|         public string GetContentType() | ||||
|         { | ||||
|             return ("vector"); | ||||
|             return "vector"; | ||||
|         } | ||||
| 
 | ||||
|         public string GetName() | ||||
|         { | ||||
|             return m_name; | ||||
|             return Name; | ||||
|         } | ||||
| 
 | ||||
|         public bool SupportsAsynchronous() | ||||
|  | @ -74,14 +74,26 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender | |||
|             return true; | ||||
|         } | ||||
| 
 | ||||
| //        public bool AlwaysIdenticalConversion(string bodyData, string extraParams) | ||||
| //        { | ||||
| //            string[] lines = GetLines(bodyData); | ||||
| //            return lines.Any((str, r) => str.StartsWith("Image")); | ||||
| //        } | ||||
| 
 | ||||
|         public byte[] ConvertUrl(string url, string extraParams) | ||||
|         { | ||||
|             return null; | ||||
|         } | ||||
| 
 | ||||
|         public byte[] ConvertStream(Stream data, string extraParams) | ||||
|         public byte[] ConvertData(string bodyData, string extraParams) | ||||
|         { | ||||
|             return null; | ||||
|             bool reuseable; | ||||
|             return Draw(bodyData, extraParams, out reuseable); | ||||
|         } | ||||
| 
 | ||||
|         private byte[] ConvertData(string bodyData, string extraParams, out bool reuseable) | ||||
|         { | ||||
|             return Draw(bodyData, extraParams, out reuseable); | ||||
|         } | ||||
| 
 | ||||
|         public bool AsyncConvertUrl(UUID id, string url, string extraParams) | ||||
|  | @ -91,7 +103,12 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender | |||
| 
 | ||||
|         public bool AsyncConvertData(UUID id, string bodyData, string extraParams) | ||||
|         { | ||||
|             Draw(bodyData, id, extraParams); | ||||
|             // XXX: This isn't actually being done asynchronously! | ||||
|             bool reuseable; | ||||
|             byte[] data = ConvertData(bodyData, extraParams, out reuseable); | ||||
| 
 | ||||
|             m_textureManager.ReturnData(id, data, reuseable); | ||||
| 
 | ||||
|             return true; | ||||
|         } | ||||
| 
 | ||||
|  | @ -152,7 +169,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender | |||
| 
 | ||||
|         public string Name | ||||
|         { | ||||
|             get { return m_name; } | ||||
|             get { return "VectorRenderModule"; } | ||||
|         } | ||||
| 
 | ||||
|         public bool IsSharedModule | ||||
|  | @ -162,7 +179,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender | |||
| 
 | ||||
|         #endregion | ||||
| 
 | ||||
|         private void Draw(string data, UUID id, string extraParams) | ||||
|         private byte[] Draw(string data, string extraParams, out bool reuseable) | ||||
|         { | ||||
|             // 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 | ||||
|             // 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 | |||
|                         } | ||||
|                     } | ||||
|          | ||||
|                     GDIDraw(data, graph, altDataDelim); | ||||
|                     GDIDraw(data, graph, altDataDelim, out reuseable); | ||||
|                 } | ||||
|      | ||||
|                 byte[] imageJ2000 = new byte[0]; | ||||
|  | @ -359,7 +376,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender | |||
|                         e.Message, e.StackTrace); | ||||
|                 } | ||||
| 
 | ||||
|                 m_textureManager.ReturnData(id, imageJ2000); | ||||
|                 return imageJ2000; | ||||
|             } | ||||
|             finally | ||||
|             { | ||||
|  | @ -434,8 +451,21 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender | |||
|         } | ||||
| */ | ||||
| 
 | ||||
|         private void GDIDraw(string data, Graphics graph, char dataDelim) | ||||
|         /// <summary> | ||||
|         /// Split input data into discrete command lines. | ||||
|         /// </summary> | ||||
|         /// <returns></returns> | ||||
|         /// <param name='data'></param> | ||||
|         /// <param name='dataDelim'></param> | ||||
|         private string[] GetLines(string data, char dataDelim) | ||||
|         { | ||||
|             char[] lineDelimiter = { dataDelim }; | ||||
|             return data.Split(lineDelimiter); | ||||
|         } | ||||
| 
 | ||||
|         private void GDIDraw(string data, Graphics graph, char dataDelim, out bool reuseable) | ||||
|         { | ||||
|             reuseable = true; | ||||
|             Point startPoint = new Point(0, 0); | ||||
|             Point endPoint = new Point(0, 0); | ||||
|             Pen drawPen = null; | ||||
|  | @ -450,11 +480,9 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender | |||
|                 myFont = new Font(fontName, fontSize); | ||||
|                 myBrush = new SolidBrush(Color.Black); | ||||
| 
 | ||||
|                 char[] lineDelimiter = {dataDelim}; | ||||
|                 char[] partsDelimiter = {','}; | ||||
|                 string[] lines = data.Split(lineDelimiter); | ||||
| 
 | ||||
|                 foreach (string line in lines) | ||||
|                 foreach (string line in GetLines(data, dataDelim)) | ||||
|                 { | ||||
|                     string nextLine = line.Trim(); | ||||
|                     //replace with switch, or even better, do some proper parsing | ||||
|  | @ -485,6 +513,10 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender | |||
|                     } | ||||
|                     else if (nextLine.StartsWith("Image")) | ||||
|                     { | ||||
|                         // We cannot reuse any generated texture involving fetching an image via HTTP since that image | ||||
|                         // can change. | ||||
|                         reuseable = false; | ||||
| 
 | ||||
|                         float x = 0; | ||||
|                         float y = 0; | ||||
|                         GetParams(partsDelimiter, ref nextLine, 5, ref x, ref y); | ||||
|  |  | |||
|  | @ -414,6 +414,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
|         private void LoadPlugins() | ||||
|         { | ||||
|             m_plugineffects = new Dictionary<string, ITerrainEffect>(); | ||||
|             LoadPlugins(Assembly.GetCallingAssembly()); | ||||
|             string plugineffectsPath = "Terrain"; | ||||
|              | ||||
|             // Load the files in the Terrain/ dir | ||||
|  | @ -427,32 +428,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
|                 try | ||||
|                 { | ||||
|                     Assembly library = Assembly.LoadFrom(file); | ||||
|                     foreach (Type pluginType in library.GetTypes()) | ||||
|                     { | ||||
|                         try | ||||
|                         { | ||||
|                             if (pluginType.IsAbstract || pluginType.IsNotPublic) | ||||
|                                 continue; | ||||
| 
 | ||||
|                             string typeName = pluginType.Name; | ||||
| 
 | ||||
|                             if (pluginType.GetInterface("ITerrainEffect", false) != null) | ||||
|                             { | ||||
|                                 ITerrainEffect terEffect = (ITerrainEffect) Activator.CreateInstance(library.GetType(pluginType.ToString())); | ||||
| 
 | ||||
|                                 InstallPlugin(typeName, terEffect); | ||||
|                             } | ||||
|                             else if (pluginType.GetInterface("ITerrainLoader", false) != null) | ||||
|                             { | ||||
|                                 ITerrainLoader terLoader = (ITerrainLoader) Activator.CreateInstance(library.GetType(pluginType.ToString())); | ||||
|                                 m_loaders[terLoader.FileExtension] = terLoader; | ||||
|                                 m_log.Info("L ... " + typeName); | ||||
|                             } | ||||
|                         } | ||||
|                         catch (AmbiguousMatchException) | ||||
|                         { | ||||
|                         } | ||||
|                     } | ||||
|                     LoadPlugins(library); | ||||
|                 } | ||||
|                 catch (BadImageFormatException) | ||||
|                 { | ||||
|  | @ -460,6 +436,36 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
|             } | ||||
|         } | ||||
| 
 | ||||
|         private void LoadPlugins(Assembly library) | ||||
|         { | ||||
|             foreach (Type pluginType in library.GetTypes()) | ||||
|             { | ||||
|                 try | ||||
|                 { | ||||
|                     if (pluginType.IsAbstract || pluginType.IsNotPublic) | ||||
|                         continue; | ||||
| 
 | ||||
|                     string typeName = pluginType.Name; | ||||
| 
 | ||||
|                     if (pluginType.GetInterface("ITerrainEffect", false) != null) | ||||
|                     { | ||||
|                         ITerrainEffect terEffect = (ITerrainEffect)Activator.CreateInstance(library.GetType(pluginType.ToString())); | ||||
| 
 | ||||
|                         InstallPlugin(typeName, terEffect); | ||||
|                     } | ||||
|                     else if (pluginType.GetInterface("ITerrainLoader", false) != null) | ||||
|                     { | ||||
|                         ITerrainLoader terLoader = (ITerrainLoader)Activator.CreateInstance(library.GetType(pluginType.ToString())); | ||||
|                         m_loaders[terLoader.FileExtension] = terLoader; | ||||
|                         m_log.Info("L ... " + typeName); | ||||
|                     } | ||||
|                 } | ||||
|                 catch (AmbiguousMatchException) | ||||
|                 { | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public void InstallPlugin(string pluginName, ITerrainEffect effect) | ||||
|         { | ||||
|             lock (m_plugineffects) | ||||
|  | @ -1176,7 +1182,8 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
| 
 | ||||
|         private void InterfaceRunPluginEffect(Object[] args) | ||||
|         { | ||||
|             if ((string) args[0] == "list") | ||||
|             string firstArg = (string)args[0]; | ||||
|             if (firstArg == "list") | ||||
|             { | ||||
|                 m_log.Info("List of loaded plugins"); | ||||
|                 foreach (KeyValuePair<string, ITerrainEffect> kvp in m_plugineffects) | ||||
|  | @ -1185,14 +1192,14 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
|                 } | ||||
|                 return; | ||||
|             } | ||||
|             if ((string) args[0] == "reload") | ||||
|             if (firstArg == "reload") | ||||
|             { | ||||
|                 LoadPlugins(); | ||||
|                 return; | ||||
|             } | ||||
|             if (m_plugineffects.ContainsKey((string) args[0])) | ||||
|             if (m_plugineffects.ContainsKey(firstArg)) | ||||
|             { | ||||
|                 m_plugineffects[(string) args[0]].RunEffect(m_channel); | ||||
|                 m_plugineffects[firstArg].RunEffect(m_channel); | ||||
|                 CheckForTerrainUpdates(); | ||||
|             } | ||||
|             else | ||||
|  |  | |||
|  | @ -33,7 +33,7 @@ namespace OpenSim.Region.Framework.Interfaces | |||
|     public interface IDynamicTextureManager | ||||
|     { | ||||
|         void RegisterRender(string handleType, IDynamicTextureRender render); | ||||
|         void ReturnData(UUID id, byte[] data); | ||||
|         void ReturnData(UUID id, byte[] data, bool isReuseable); | ||||
| 
 | ||||
|         UUID AddDynamicTextureURL(UUID simID, UUID primID, string contentType, string url, string extraParams, | ||||
|                                     int updateTimer); | ||||
|  | @ -113,8 +113,20 @@ namespace OpenSim.Region.Framework.Interfaces | |||
|         string GetName(); | ||||
|         string GetContentType(); | ||||
|         bool SupportsAsynchronous(); | ||||
| 
 | ||||
| //        /// <summary> | ||||
| //        /// Return true if converting the input body and extra params data will always result in the same byte[] array | ||||
| //        /// </summary> | ||||
| //        /// <remarks> | ||||
| //        /// This method allows the caller to use a previously generated asset if it has one. | ||||
| //        /// </remarks> | ||||
| //        /// <returns></returns> | ||||
| //        /// <param name='bodyData'></param> | ||||
| //        /// <param name='extraParams'></param> | ||||
| //        bool AlwaysIdenticalConversion(string bodyData, string extraParams); | ||||
| 
 | ||||
|         byte[] ConvertUrl(string url, string extraParams); | ||||
|         byte[] ConvertStream(Stream data, string extraParams); | ||||
|         byte[] ConvertData(string bodyData, string extraParams); | ||||
|         bool AsyncConvertUrl(UUID id, string url, string extraParams); | ||||
|         bool AsyncConvertData(UUID id, string bodyData, string extraParams); | ||||
|         void GetDrawStringSize(string text, string fontName, int fontSize,  | ||||
|  |  | |||
|  | @ -39,6 +39,8 @@ namespace OpenSim.Region.Framework.Interfaces | |||
|         UUID RequestSecureURL(IScriptModule engine, SceneObjectPart host, UUID itemID); | ||||
|         void ReleaseURL(string url); | ||||
|         void HttpResponse(UUID request, int status, string body); | ||||
|         void HttpContentType(UUID request, string type); | ||||
|          | ||||
|         string GetHttpHeader(UUID request, string header); | ||||
|         int GetFreeUrls(); | ||||
| 
 | ||||
|  |  | |||
|  | @ -50,8 +50,40 @@ using OpenSim.Tests.Common.Mock; | |||
| namespace OpenSim.Region.Framework.Tests | ||||
| { | ||||
|     [TestFixture] | ||||
|     public class UserInventoryTests | ||||
|     public class UserInventoryTests : OpenSimTestCase | ||||
|     { | ||||
|         [Test] | ||||
|         public void TestCreateInventoryFolders() | ||||
|         { | ||||
|             TestHelpers.InMethod(); | ||||
| //            TestHelpers.EnableLogging(); | ||||
| 
 | ||||
|             // For this test both folders will have the same name which is legal in SL user inventories. | ||||
|             string foldersName = "f1"; | ||||
| 
 | ||||
|             Scene scene = new SceneHelpers().SetupScene(); | ||||
|             UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene, TestHelpers.ParseTail(1001)); | ||||
| 
 | ||||
|             UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, user1.PrincipalID, foldersName); | ||||
| 
 | ||||
|             List<InventoryFolderBase> oneFolder | ||||
|                 = UserInventoryHelpers.GetInventoryFolders(scene.InventoryService, user1.PrincipalID, foldersName); | ||||
| 
 | ||||
|             Assert.That(oneFolder.Count, Is.EqualTo(1)); | ||||
|             InventoryFolderBase firstRetrievedFolder = oneFolder[0]; | ||||
|             Assert.That(firstRetrievedFolder.Name, Is.EqualTo(foldersName)); | ||||
| 
 | ||||
|             UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, user1.PrincipalID, foldersName); | ||||
| 
 | ||||
|             List<InventoryFolderBase> twoFolders | ||||
|                 = UserInventoryHelpers.GetInventoryFolders(scene.InventoryService, user1.PrincipalID, foldersName); | ||||
| 
 | ||||
|             Assert.That(twoFolders.Count, Is.EqualTo(2)); | ||||
|             Assert.That(twoFolders[0].Name, Is.EqualTo(foldersName)); | ||||
|             Assert.That(twoFolders[1].Name, Is.EqualTo(foldersName)); | ||||
|             Assert.That(twoFolders[0].ID, Is.Not.EqualTo(twoFolders[1].ID)); | ||||
|         } | ||||
| 
 | ||||
|         [Test] | ||||
|         public void TestGiveInventoryItem() | ||||
|         { | ||||
|  | @ -83,7 +115,7 @@ namespace OpenSim.Region.Framework.Tests | |||
|         public void TestGiveInventoryFolder() | ||||
|         { | ||||
|             TestHelpers.InMethod(); | ||||
| //            log4net.Config.XmlConfigurator.Configure(); | ||||
| //            TestHelpers.EnableLogging(); | ||||
|              | ||||
|             Scene scene = new SceneHelpers().SetupScene(); | ||||
|             UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene, TestHelpers.ParseTail(1001)); | ||||
|  |  | |||
|  | @ -7208,7 +7208,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|         { | ||||
|             m_host.AddScriptLPS(1); | ||||
| 
 | ||||
|             setLinkPrimParams(ScriptBaseClass.LINK_THIS, rules); | ||||
|             setLinkPrimParams(ScriptBaseClass.LINK_THIS, rules, "llSetPrimitiveParams"); | ||||
| 
 | ||||
|             ScriptSleep(200); | ||||
|         } | ||||
|  | @ -7217,7 +7217,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|         { | ||||
|             m_host.AddScriptLPS(1); | ||||
| 
 | ||||
|             setLinkPrimParams(linknumber, rules); | ||||
|             setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams"); | ||||
| 
 | ||||
|             ScriptSleep(200); | ||||
|         } | ||||
|  | @ -7226,17 +7226,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|         { | ||||
|             m_host.AddScriptLPS(1); | ||||
| 
 | ||||
|             setLinkPrimParams(linknumber, rules); | ||||
|             setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast"); | ||||
|         } | ||||
| 
 | ||||
|         protected void setLinkPrimParams(int linknumber, LSL_List rules) | ||||
|         protected void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc) | ||||
|         { | ||||
|             List<SceneObjectPart> parts = GetLinkParts(linknumber); | ||||
| 
 | ||||
|             LSL_List remaining = null; | ||||
|             uint rulesParsed = 0; | ||||
| 
 | ||||
|             foreach (SceneObjectPart part in parts) | ||||
|                 remaining = SetPrimParams(part, rules); | ||||
|                 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed); | ||||
| 
 | ||||
|             while (remaining != null && remaining.Length > 2) | ||||
|             { | ||||
|  | @ -7245,13 +7246,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|                 parts = GetLinkParts(linknumber); | ||||
| 
 | ||||
|                 foreach (SceneObjectPart part in parts) | ||||
|                     remaining = SetPrimParams(part, rules); | ||||
|                     remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules) | ||||
|         protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed) | ||||
|         { | ||||
|             int idx = 0; | ||||
|             int idxStart = 0; | ||||
| 
 | ||||
|             bool positionChanged = false; | ||||
|             LSL_Vector currentPosition = GetPartLocalPos(part); | ||||
|  | @ -7260,9 +7262,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|             { | ||||
|                 while (idx < rules.Length) | ||||
|                 { | ||||
|                     ++rulesParsed; | ||||
|                     int code = rules.GetLSLIntegerItem(idx++); | ||||
| 
 | ||||
|                     int remain = rules.Length - idx; | ||||
|                     idxStart = idx; | ||||
| 
 | ||||
|                     int face; | ||||
|                     LSL_Vector v; | ||||
|  | @ -7639,7 +7643,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|             } | ||||
|             catch (InvalidCastException e) | ||||
|             { | ||||
|                 ShoutError(e.Message); | ||||
|                 ShoutError(string.Format( | ||||
|                         "{0} error running rule #{1}: arg #{2} ", | ||||
|                         originFunc, rulesParsed, idx - idxStart) + e.Message); | ||||
|             } | ||||
|             finally | ||||
|             { | ||||
|  | @ -10113,31 +10119,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|         public LSL_Float llListStatistics(int operation, LSL_List src) | ||||
|         { | ||||
|             m_host.AddScriptLPS(1); | ||||
|             LSL_List nums = LSL_List.ToDoubleList(src); | ||||
|             switch (operation) | ||||
|             { | ||||
|                 case ScriptBaseClass.LIST_STAT_RANGE: | ||||
|                     return nums.Range(); | ||||
|                     return src.Range(); | ||||
|                 case ScriptBaseClass.LIST_STAT_MIN: | ||||
|                     return nums.Min(); | ||||
|                     return src.Min(); | ||||
|                 case ScriptBaseClass.LIST_STAT_MAX: | ||||
|                     return nums.Max(); | ||||
|                     return src.Max(); | ||||
|                 case ScriptBaseClass.LIST_STAT_MEAN: | ||||
|                     return nums.Mean(); | ||||
|                     return src.Mean(); | ||||
|                 case ScriptBaseClass.LIST_STAT_MEDIAN: | ||||
|                     return nums.Median(); | ||||
|                     return LSL_List.ToDoubleList(src).Median(); | ||||
|                 case ScriptBaseClass.LIST_STAT_NUM_COUNT: | ||||
|                     return nums.NumericLength(); | ||||
|                     return src.NumericLength(); | ||||
|                 case ScriptBaseClass.LIST_STAT_STD_DEV: | ||||
|                     return nums.StdDev(); | ||||
|                     return src.StdDev(); | ||||
|                 case ScriptBaseClass.LIST_STAT_SUM: | ||||
|                     return nums.Sum(); | ||||
|                     return src.Sum(); | ||||
|                 case ScriptBaseClass.LIST_STAT_SUM_SQUARES: | ||||
|                     return nums.SumSqrs(); | ||||
|                     return src.SumSqrs(); | ||||
|                 case ScriptBaseClass.LIST_STAT_GEOMETRIC_MEAN: | ||||
|                     return nums.GeometricMean(); | ||||
|                     return src.GeometricMean(); | ||||
|                 case ScriptBaseClass.LIST_STAT_HARMONIC_MEAN: | ||||
|                     return nums.HarmonicMean(); | ||||
|                     return src.HarmonicMean(); | ||||
|                 default: | ||||
|                     return 0.0; | ||||
|             } | ||||
|  | @ -10761,7 +10766,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|             return tid.ToString(); | ||||
|         } | ||||
| 
 | ||||
|         public void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules) | ||||
|         public void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules, string originFunc) | ||||
|         { | ||||
|             SceneObjectPart obj = World.GetSceneObjectPart(new UUID(prim)); | ||||
|             if (obj == null) | ||||
|  | @ -10770,14 +10775,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|             if (obj.OwnerID != m_host.OwnerID) | ||||
|                 return; | ||||
| 
 | ||||
|             LSL_List remaining = SetPrimParams(obj, rules); | ||||
|             uint rulesParsed = 0; | ||||
|             LSL_List remaining = SetPrimParams(obj, rules, originFunc, ref rulesParsed); | ||||
| 
 | ||||
|             while ((object)remaining != null && remaining.Length > 2) | ||||
|             { | ||||
|                 LSL_Integer newLink = remaining.GetLSLIntegerItem(0); | ||||
|                 LSL_List newrules = remaining.GetSublist(1, -1); | ||||
|                 foreach(SceneObjectPart part in GetLinkParts(obj, newLink)){ | ||||
|                     remaining = SetPrimParams(part, newrules); | ||||
|                     remaining = SetPrimParams(part, newrules, originFunc, ref rulesParsed); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  |  | |||
|  | @ -140,12 +140,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|         internal float m_ScriptDistanceFactor = 1.0f; | ||||
|         internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >(); | ||||
| 
 | ||||
|         protected IUrlModule m_UrlModule = null; | ||||
| 
 | ||||
|         public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item) | ||||
|         { | ||||
|             m_ScriptEngine = ScriptEngine; | ||||
|             m_host = host; | ||||
|             m_item = item; | ||||
| 
 | ||||
|             m_UrlModule = m_ScriptEngine.World.RequestModuleInterface<IUrlModule>(); | ||||
| 
 | ||||
|             if (m_ScriptEngine.Config.GetBoolean("AllowOSFunctions", false)) | ||||
|                 m_OSFunctionsEnabled = true; | ||||
| 
 | ||||
|  | @ -2988,7 +2992,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|             m_host.AddScriptLPS(1); | ||||
|             InitLSL(); | ||||
|              | ||||
|             m_LSL_Api.SetPrimitiveParamsEx(prim, rules); | ||||
|             m_LSL_Api.SetPrimitiveParamsEx(prim, rules, "osSetPrimitiveParams"); | ||||
|         } | ||||
|          | ||||
|         /// <summary> | ||||
|  | @ -3358,5 +3362,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
| 
 | ||||
|             return new LSL_Key(m_host.ParentGroup.FromPartID.ToString()); | ||||
|         } | ||||
|     } | ||||
|   | ||||
|         /// <summary> | ||||
|         /// Sets the response type for an HTTP request/response | ||||
|         /// </summary> | ||||
|         /// <returns></returns> | ||||
|         public void osSetContentType(LSL_Key id, string type) | ||||
|         { | ||||
|             CheckThreatLevel(ThreatLevel.High,"osSetResponseType"); | ||||
|             if (m_UrlModule != null) | ||||
|                 m_UrlModule.HttpContentType(new UUID(id),type); | ||||
|         } | ||||
|          | ||||
|    } | ||||
| } | ||||
|  | @ -424,7 +424,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces | |||
|         LSL_String llXorBase64StringsCorrect(string str1, string str2); | ||||
|               void print(string str); | ||||
| 
 | ||||
|               void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules); | ||||
|               void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules, string originFunc); | ||||
|           LSL_List GetPrimitiveParamsEx(LSL_Key prim, LSL_List rules); | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -40,16 +40,75 @@ using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; | |||
| 
 | ||||
| namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces | ||||
| { | ||||
|     /// <summary> | ||||
|     /// To permit region owners to enable the extended scripting functionality | ||||
|     /// of OSSL, without allowing malicious scripts to access potentially | ||||
|     /// troublesome functions, each OSSL function is assigned a threat level, | ||||
|     /// and access to the functions is granted or denied based on a default | ||||
|     /// threshold set in OpenSim.ini (which can be overridden for individual | ||||
|     /// functions on a case-by-case basis) | ||||
|     /// </summary> | ||||
|     public enum ThreatLevel | ||||
|     { | ||||
|         // Not documented, presumably means permanently disabled ? | ||||
|         NoAccess = -1, | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Function is no threat at all. It doesn't constitute a threat to  | ||||
|         /// either users or the system and has no known side effects. | ||||
|         /// </summary> | ||||
|         None = 0, | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Abuse of this command can cause a nuisance to the region operator, | ||||
|         /// such as log message spew. | ||||
|         /// </summary> | ||||
|         Nuisance = 1, | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Extreme levels of abuse of this function can cause impaired  | ||||
|         /// functioning of the region, or very gullible users can be tricked | ||||
|         /// into experiencing harmless effects. | ||||
|         /// </summary> | ||||
|         VeryLow = 2, | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Intentional abuse can cause crashes or malfunction under certain | ||||
|         /// circumstances, which can be easily rectified; or certain users can | ||||
|         /// be tricked into certain situations in an avoidable manner. | ||||
|         /// </summary> | ||||
|         Low = 3, | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Intentional abuse can cause denial of service and crashes with | ||||
|         /// potential of data or state loss; or trusting users can be tricked  | ||||
|         /// into embarrassing or uncomfortable situations. | ||||
|         /// </summary> | ||||
|         Moderate = 4, | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Casual abuse can cause impaired functionality or temporary denial | ||||
|         /// of service conditions. Intentional abuse can easily cause crashes | ||||
|         /// with potential data loss, or can be used to trick experienced and | ||||
|         /// cautious users into unwanted situations, or changes global data | ||||
|         /// permanently and without undo ability. | ||||
|         /// </summary> | ||||
|         High = 5, | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Even normal use may, depending on the number of instances, or | ||||
|         /// frequency of use, result in severe service impairment or crash | ||||
|         /// with loss of data, or can be used to cause unwanted or harmful | ||||
|         /// effects on users without giving the user a means to avoid it. | ||||
|         /// </summary> | ||||
|         VeryHigh = 6, | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Even casual use is a danger to region stability, or function allows | ||||
|         /// console or OS command execution, or function allows taking money | ||||
|         /// without consent, or allows deletion or modification of user data, | ||||
|         /// or allows the compromise of sensitive data by design. | ||||
|         /// </summary> | ||||
|         Severe = 7 | ||||
|     }; | ||||
| 
 | ||||
|  | @ -306,5 +365,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces | |||
|         /// </summary> | ||||
|         /// <returns>Rezzing object key or NULL_KEY if rezzed by agent or otherwise unknown.</returns> | ||||
|         LSL_Key osGetRezzingObject(); | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Sets the response type for an HTTP request/response | ||||
|         /// </summary> | ||||
|         /// <returns></returns> | ||||
|         void osSetContentType(LSL_Key id, string type); | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -955,5 +955,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase | |||
|         { | ||||
|             return m_OSSL_Functions.osGetRezzingObject(); | ||||
|         } | ||||
| 
 | ||||
|         public void osSetContentType(LSL_Key id, string type) | ||||
|         { | ||||
|             m_OSSL_Functions.osSetContentType(id,type); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -1137,7 +1137,7 @@ namespace OpenSim.Region.ScriptEngine.Shared | |||
|             { | ||||
|                 list ret = new list(); | ||||
|                 double entry; | ||||
|                 for (int i = 0; i < src.Data.Length - 1; i++) | ||||
|                 for (int i = 0; i < src.Data.Length; i++) | ||||
|                 { | ||||
|                     if (double.TryParse(src.Data[i].ToString(), NumberStyles.Float, Culture.NumberFormatInfo, out entry)) | ||||
|                     { | ||||
|  |  | |||
|  | @ -94,6 +94,7 @@ namespace OpenSim.Services.InventoryService | |||
| 
 | ||||
|             m_Database = LoadPlugin<IXInventoryData>(dllName, | ||||
|                     new Object[] {connString, String.Empty}); | ||||
| 
 | ||||
|             if (m_Database == null) | ||||
|                 throw new Exception("Could not find a storage interface in the given module"); | ||||
|         } | ||||
|  | @ -326,7 +327,7 @@ namespace OpenSim.Services.InventoryService | |||
|             if (check != null) | ||||
|                 return false; | ||||
| 
 | ||||
|             if (folder.Type != (short)AssetType.Folder || folder.Type != (short)AssetType.Unknown) | ||||
|             if (folder.Type != (short)AssetType.Folder && folder.Type != (short)AssetType.Unknown) | ||||
|             { | ||||
|                 InventoryFolderBase rootFolder = GetRootFolder(folder.Owner); | ||||
| 
 | ||||
|  |  | |||
|  | @ -245,7 +245,7 @@ namespace OpenSim.Tests.Common | |||
|             config.AddConfig("Modules"); | ||||
|             config.AddConfig("InventoryService"); | ||||
|             config.Configs["Modules"].Set("InventoryServices", "LocalInventoryServicesConnector"); | ||||
|             config.Configs["InventoryService"].Set("LocalServiceModule", "OpenSim.Services.InventoryService.dll:InventoryService"); | ||||
|             config.Configs["InventoryService"].Set("LocalServiceModule", "OpenSim.Services.InventoryService.dll:XInventoryService"); | ||||
|             config.Configs["InventoryService"].Set("StorageProvider", "OpenSim.Tests.Common.dll"); | ||||
| 
 | ||||
|             LocalInventoryServicesConnector inventoryService = new LocalInventoryServicesConnector(); | ||||
|  |  | |||
|  | @ -199,7 +199,9 @@ namespace OpenSim.Tests.Common | |||
|             string[] components = path.Split(new string[] { PATH_DELIMITER }, 2, StringSplitOptions.None); | ||||
| 
 | ||||
|             InventoryFolderBase newFolder  | ||||
|                 = new InventoryFolderBase(UUID.Random(), components[0], parentFolder.Owner, parentFolder.ID); | ||||
|                 = new InventoryFolderBase( | ||||
|                     UUID.Random(), components[0], parentFolder.Owner, (short)AssetType.Unknown, parentFolder.ID, 0); | ||||
|              | ||||
|             inventoryService.AddFolder(newFolder); | ||||
| 
 | ||||
|             if (components.Length > 1) | ||||
|  |  | |||
|  | @ -0,0 +1,131 @@ | |||
| /* | ||||
|  * Copyright (c) Contributors, http://opensimulator.org/ | ||||
|  * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||||
|  * | ||||
|  * Redistribution and use in source and binary forms, with or without | ||||
|  * modification, are permitted provided that the following conditions are met: | ||||
|  *     * Redistributions of source code must retain the above copyright | ||||
|  *       notice, this list of conditions and the following disclaimer. | ||||
|  *     * Redistributions in binary form must reproduce the above copyright | ||||
|  *       notice, this list of conditions and the following disclaimer in the | ||||
|  *       documentation and/or other materials provided with the distribution. | ||||
|  *     * Neither the name of the OpenSimulator Project nor the | ||||
|  *       names of its contributors may be used to endorse or promote products | ||||
|  *       derived from this software without specific prior written permission. | ||||
|  * | ||||
|  * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||||
|  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||||
|  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||||
|  * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||||
|  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||||
|  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||||
|  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||||
|  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||||
|  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||||
|  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
|  */ | ||||
| 
 | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using System.Reflection; | ||||
| using log4net; | ||||
| using OpenMetaverse; | ||||
| using OpenSim.Framework; | ||||
| using OpenSim.Data; | ||||
| 
 | ||||
| namespace OpenSim.Tests.Common.Mock | ||||
| { | ||||
|     public class TestXInventoryDataPlugin : IXInventoryData | ||||
|     { | ||||
|         private Dictionary<UUID, XInventoryFolder> m_allFolders = new Dictionary<UUID, XInventoryFolder>(); | ||||
|         private Dictionary<UUID, XInventoryItem> m_allItems = new Dictionary<UUID, XInventoryItem>(); | ||||
| 
 | ||||
|         public TestXInventoryDataPlugin(string conn, string realm) {} | ||||
| 
 | ||||
|         public XInventoryItem[] GetItems(string[] fields, string[] vals) | ||||
|         { | ||||
|             List<XInventoryItem> origItems = Get<XInventoryItem>(fields, vals, m_allItems.Values.ToList()); | ||||
| 
 | ||||
|             return origItems.Select(i => i.Clone()).ToArray(); | ||||
|         } | ||||
| 
 | ||||
|         public XInventoryFolder[] GetFolders(string[] fields, string[] vals) | ||||
|         { | ||||
|             List<XInventoryFolder> origFolders | ||||
|                 = Get<XInventoryFolder>(fields, vals, m_allFolders.Values.ToList()); | ||||
| 
 | ||||
|             return origFolders.Select(f => f.Clone()).ToArray(); | ||||
|         } | ||||
| 
 | ||||
|         private List<T> Get<T>(string[] fields, string[] vals, List<T> inputEntities) | ||||
|         { | ||||
|             List<T> entities = inputEntities; | ||||
| 
 | ||||
|             for (int i = 0; i < fields.Length; i++) | ||||
|             { | ||||
|                 entities | ||||
|                     = entities.Where( | ||||
|                         e => | ||||
|                         { | ||||
|                             FieldInfo fi = typeof(T).GetField(fields[i]); | ||||
|                             if (fi == null) | ||||
|                                 throw new NotImplementedException(string.Format("No field {0} for val {1}", fields[i], vals[i])); | ||||
| 
 | ||||
|                             return fi.GetValue(e).ToString() == vals[i]; | ||||
|                         } | ||||
|                     ).ToList(); | ||||
|             } | ||||
| 
 | ||||
|             return entities; | ||||
|         } | ||||
| 
 | ||||
|         public bool StoreFolder(XInventoryFolder folder) | ||||
|         { | ||||
|             m_allFolders[folder.folderID] = folder.Clone(); | ||||
| 
 | ||||
| //            Console.WriteLine("Added folder {0} {1}", folder.folderName, folder.folderID); | ||||
| 
 | ||||
|             return true; | ||||
|         } | ||||
| 
 | ||||
|         public bool StoreItem(XInventoryItem item) | ||||
|         { | ||||
|             m_allItems[item.inventoryID] = item.Clone(); | ||||
| 
 | ||||
| //            Console.WriteLine("Added item {0} {1}, creator {2}, owner {3}", item.inventoryName, item.inventoryID, item.creatorID, item.avatarID); | ||||
| 
 | ||||
|             return true; | ||||
|         } | ||||
| 
 | ||||
|         public bool DeleteFolders(string field, string val) | ||||
|         { | ||||
|             return DeleteFolders(new string[] { field }, new string[] { val }); | ||||
|         } | ||||
| 
 | ||||
|         public bool DeleteFolders(string[] fields, string[] vals) | ||||
|         { | ||||
|             XInventoryFolder[] foldersToDelete = GetFolders(fields, vals); | ||||
|             Array.ForEach(foldersToDelete, f => m_allFolders.Remove(f.folderID)); | ||||
| 
 | ||||
|             return true; | ||||
|         } | ||||
| 
 | ||||
|         public bool DeleteItems(string field, string val) | ||||
|         { | ||||
|             return DeleteItems(new string[] { field }, new string[] { val }); | ||||
|         } | ||||
| 
 | ||||
|         public bool DeleteItems(string[] fields, string[] vals) | ||||
|         { | ||||
|             XInventoryItem[] itemsToDelete = GetItems(fields, vals); | ||||
|             Array.ForEach(itemsToDelete, i => m_allItems.Remove(i.inventoryID)); | ||||
| 
 | ||||
|             return true; | ||||
|         } | ||||
| 
 | ||||
|         public bool MoveItem(string id, string newParent) { throw new NotImplementedException(); } | ||||
|         public XInventoryItem[] GetActiveGestures(UUID principalID) { throw new NotImplementedException(); } | ||||
|         public int GetAssetPermissions(UUID principalID, UUID assetID) { throw new NotImplementedException(); } | ||||
|     } | ||||
| } | ||||
|  | @ -95,6 +95,7 @@ namespace OpenSim.Tests.Common | |||
|         public static void EnableLogging() | ||||
|         { | ||||
|             log4net.Config.XmlConfigurator.Configure(EnableLoggingConfigStream); | ||||
|             EnableLoggingConfigStream.Position = 0; | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|  |  | |||
|  | @ -47,10 +47,10 @@ using OpenSim.Services.AvatarService; | |||
| using OpenSim.Tests.Common; | ||||
| using OpenSim.Tests.Common.Mock; | ||||
| 
 | ||||
| namespace OpenSim.Tests.Torture | ||||
| namespace OpenSim.Tests.Performance | ||||
| { | ||||
|     /// <summary> | ||||
|     /// NPC torture tests | ||||
|     /// NPC performance tests | ||||
|     /// </summary> | ||||
|     /// <remarks> | ||||
|     /// Don't rely on the numbers given by these tests - they will vary a lot depending on what is already cached, | ||||
|  | @ -58,7 +58,7 @@ namespace OpenSim.Tests.Torture | |||
|     /// earlier tests. | ||||
|     /// </remarks> | ||||
|     [TestFixture] | ||||
|     public class NPCTortureTests | ||||
|     public class NPCPerformanceTests | ||||
|     { | ||||
|         private TestScene scene; | ||||
|         private AvatarFactoryModule afm; | ||||
|  | @ -36,10 +36,10 @@ using OpenSim.Region.Framework.Scenes; | |||
| using OpenSim.Tests.Common; | ||||
| using OpenSim.Tests.Common.Mock; | ||||
| 
 | ||||
| namespace OpenSim.Tests.Torture | ||||
| namespace OpenSim.Tests.Performance | ||||
| { | ||||
|     /// <summary> | ||||
|     /// Object torture tests | ||||
|     /// Object performance tests | ||||
|     /// </summary> | ||||
|     /// <remarks> | ||||
|     /// Don't rely on the numbers given by these tests - they will vary a lot depending on what is already cached, | ||||
|  | @ -47,7 +47,7 @@ namespace OpenSim.Tests.Torture | |||
|     /// earlier tests. | ||||
|     /// </remarks> | ||||
|     [TestFixture] | ||||
|     public class ObjectTortureTests | ||||
|     public class ObjectPerformanceTests | ||||
|     { | ||||
|         [TearDown] | ||||
|         public void TearDown() | ||||
|  | @ -42,10 +42,10 @@ using OpenSim.Region.ScriptEngine.XEngine; | |||
| using OpenSim.Tests.Common; | ||||
| using OpenSim.Tests.Common.Mock; | ||||
| 
 | ||||
| namespace OpenSim.Tests.Torture | ||||
| namespace OpenSim.Tests.Performance | ||||
| { | ||||
|     /// <summary> | ||||
|     /// Script torture tests | ||||
|     /// Script performance tests | ||||
|     /// </summary> | ||||
|     /// <remarks> | ||||
|     /// Don't rely on the numbers given by these tests - they will vary a lot depending on what is already cached, | ||||
|  | @ -53,7 +53,7 @@ namespace OpenSim.Tests.Torture | |||
|     /// earlier tests. | ||||
|     /// </remarks> | ||||
|     [TestFixture] | ||||
|     public class ScriptTortureTests | ||||
|     public class ScriptPerformanceTests | ||||
|     { | ||||
|         private TestScene m_scene; | ||||
|         private XEngine m_xEngine; | ||||
|  | @ -0,0 +1,132 @@ | |||
| /* | ||||
|  * Copyright (c) Contributors, http://opensimulator.org/ | ||||
|  * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||||
|  * | ||||
|  * Redistribution and use in source and binary forms, with or without | ||||
|  * modification, are permitted provided that the following conditions are met: | ||||
|  *     * Redistributions of source code must retain the above copyright | ||||
|  *       notice, this list of conditions and the following disclaimer. | ||||
|  *     * Redistributions in binary form must reproduce the above copyright | ||||
|  *       notice, this list of conditions and the following disclaimer in the | ||||
|  *       documentation and/or other materials provided with the distribution. | ||||
|  *     * Neither the name of the OpenSimulator Project nor the | ||||
|  *       names of its contributors may be used to endorse or promote products | ||||
|  *       derived from this software without specific prior written permission. | ||||
|  * | ||||
|  * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||||
|  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||||
|  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||||
|  * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||||
|  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||||
|  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||||
|  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||||
|  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||||
|  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||||
|  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
|  */ | ||||
| 
 | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.IO; | ||||
| using System.Linq; | ||||
| using System.Reflection; | ||||
| using System.Threading; | ||||
| using log4net.Config; | ||||
| using NUnit.Framework; | ||||
| using OpenMetaverse; | ||||
| using OpenMetaverse.Assets; | ||||
| using OpenSim.Framework; | ||||
| using OpenSim.Region.CoreModules.Scripting.DynamicTexture; | ||||
| using OpenSim.Region.CoreModules.Scripting.VectorRender; | ||||
| using OpenSim.Region.Framework.Scenes; | ||||
| using OpenSim.Region.Framework.Scenes.Serialization; | ||||
| using OpenSim.Tests.Common; | ||||
| using OpenSim.Tests.Common.Mock; | ||||
| 
 | ||||
| namespace OpenSim.Tests.Stress | ||||
| { | ||||
|     [TestFixture] | ||||
|     public class VectorRenderModuleStressTests : OpenSimTestCase | ||||
|     { | ||||
|         public Scene Scene { get; private set; } | ||||
|         public DynamicTextureModule Dtm { get; private set; } | ||||
|         public VectorRenderModule Vrm { get; private set; } | ||||
| 
 | ||||
|         private void SetupScene(bool reuseTextures) | ||||
|         { | ||||
|             Scene = new SceneHelpers().SetupScene(); | ||||
| 
 | ||||
|             Dtm = new DynamicTextureModule(); | ||||
|             Dtm.ReuseTextures = reuseTextures; | ||||
| 
 | ||||
|             Vrm = new VectorRenderModule(); | ||||
| 
 | ||||
|             SceneHelpers.SetupSceneModules(Scene, Dtm, Vrm); | ||||
|         } | ||||
| 
 | ||||
|         [Test] | ||||
|         public void TestConcurrentRepeatedDraw() | ||||
|         { | ||||
|             int threads = 4; | ||||
|             TestHelpers.InMethod(); | ||||
| 
 | ||||
|             SetupScene(false); | ||||
| 
 | ||||
|             List<Drawer> drawers = new List<Drawer>(); | ||||
| 
 | ||||
|             for (int i = 0; i < threads; i++) | ||||
|             { | ||||
|                 Drawer d = new Drawer(this, i); | ||||
|                 drawers.Add(d); | ||||
|                 Console.WriteLine("Starting drawer {0}", i); | ||||
|                 Util.FireAndForget(o => d.Draw()); | ||||
|             } | ||||
| 
 | ||||
|             Thread.Sleep(10 * 60 * 1000); | ||||
| 
 | ||||
|             drawers.ForEach(d => d.Ready = false); | ||||
|             drawers.ForEach(d => Console.WriteLine("Drawer {0} drew {1} textures", d.Number, d.Pass + 1)); | ||||
|         } | ||||
| 
 | ||||
|         class Drawer | ||||
|         { | ||||
|             public int Number { get; private set; } | ||||
|             public int Pass { get; private set; } | ||||
|             public bool Ready { get; set; } | ||||
| 
 | ||||
|             private VectorRenderModuleStressTests m_tests; | ||||
| 
 | ||||
|             public Drawer(VectorRenderModuleStressTests tests, int number) | ||||
|             { | ||||
|                 m_tests = tests; | ||||
|                 Number = number; | ||||
|                 Ready = true; | ||||
|             } | ||||
| 
 | ||||
|             public void Draw() | ||||
|             { | ||||
|                 SceneObjectGroup so = SceneHelpers.AddSceneObject(m_tests.Scene); | ||||
|                  | ||||
|                 while (Ready) | ||||
|                 { | ||||
|                     UUID originalTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID; | ||||
| 
 | ||||
|                     // Ensure unique text | ||||
|                     string text = string.Format("{0:D2}{1}", Number, Pass); | ||||
| 
 | ||||
|                     m_tests.Dtm.AddDynamicTextureData( | ||||
|                         m_tests.Scene.RegionInfo.RegionID, | ||||
|                         so.UUID, | ||||
|                         m_tests.Vrm.GetContentType(), | ||||
|                         string.Format("PenColour BLACK; MoveTo 40,220; FontSize 32; Text {0};", text), | ||||
|                         "", | ||||
|                         0); | ||||
|      | ||||
|                     Assert.That(originalTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID)); | ||||
| 
 | ||||
|                     Pass++; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										42
									
								
								prebuild.xml
								
								
								
								
							
							
						
						
									
										42
									
								
								prebuild.xml
								
								
								
								
							|  | @ -3289,7 +3289,47 @@ | |||
|       </Files> | ||||
|     </Project> | ||||
| 
 | ||||
|     <Project frameworkVersion="v3_5" name="OpenSim.Tests.Torture" path="OpenSim/Tests/Torture" type="Library"> | ||||
|     <Project frameworkVersion="v3_5" name="OpenSim.Tests.Stress" path="OpenSim/Tests/Stress" type="Library"> | ||||
|       <Configuration name="Debug"> | ||||
|         <Options> | ||||
|           <OutputPath>../../../bin/</OutputPath> | ||||
|         </Options> | ||||
|       </Configuration> | ||||
|       <Configuration name="Release"> | ||||
|         <Options> | ||||
|           <OutputPath>../../../bin/</OutputPath> | ||||
|         </Options> | ||||
|       </Configuration> | ||||
| 
 | ||||
|       <ReferencePath>../../../bin/</ReferencePath> | ||||
|       <Reference name="System"/> | ||||
|       <Reference name="System.Xml"/> | ||||
|       <Reference name="System.Data"/> | ||||
|       <Reference name="log4net" path="../../../bin/"/> | ||||
|       <Reference name="Nini" path="../../../bin/"/> | ||||
|       <Reference name="nunit.framework" path="../../../bin/"/> | ||||
|       <Reference name="OpenMetaverse" path="../../../bin/"/> | ||||
|       <Reference name="OpenMetaverseTypes" path="../../../bin/"/> | ||||
|       <Reference name="OpenMetaverse.StructuredData" path="../../../bin/"/> | ||||
|       <Reference name="XMLRPC" path="../../../bin/"/> | ||||
|       <Reference name="OpenSim.Framework"/> | ||||
|       <Reference name="OpenSim.Framework.Communications"/> | ||||
|       <Reference name="OpenSim.Framework.Console"/> | ||||
|       <Reference name="OpenSim.Framework.Servers.HttpServer"/> | ||||
|       <Reference name="OpenSim.Region.CoreModules"/> | ||||
|       <Reference name="OpenSim.Region.Framework"/> | ||||
|       <Reference name="OpenSim.Region.OptionalModules"/> | ||||
|       <Reference name="OpenSim.Region.ScriptEngine.Shared"/> | ||||
|       <Reference name="OpenSim.Region.ScriptEngine.XEngine"/> | ||||
|       <Reference name="OpenSim.Services.Interfaces"/> | ||||
|       <Reference name="OpenSim.Services.AvatarService"/> | ||||
|       <Reference name="OpenSim.Tests.Common"/> | ||||
|       <Files> | ||||
|         <Match pattern="*.cs" recurse="false"/> | ||||
|       </Files> | ||||
|     </Project> | ||||
| 
 | ||||
|     <Project frameworkVersion="v3_5" name="OpenSim.Tests.Performance" path="OpenSim/Tests/Performance" type="Library"> | ||||
|       <Configuration name="Debug"> | ||||
|         <Options> | ||||
|           <OutputPath>../../../bin/</OutputPath> | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 BlueWall
						BlueWall