diff --git a/OpenSim/Region/Framework/Scenes/Scripting/ScriptUtils.cs b/OpenSim/Region/Framework/Scenes/Scripting/ScriptUtils.cs new file mode 100644 index 0000000000..d8aa2584a6 --- /dev/null +++ b/OpenSim/Region/Framework/Scenes/Scripting/ScriptUtils.cs @@ -0,0 +1,122 @@ +/* + * 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 OpenMetaverse; +using OpenSim.Framework; + +namespace OpenSim.Region.Framework.Scenes.Scripting +{ + /// + /// Utility functions for use by scripts manipulating the scene. + /// + public static class ScriptUtils + { + /// + /// Get an asset id given an item name and an item type. + /// + /// UUID.Zero if the name and type did not match any item. + /// + /// + /// + public static UUID GetAssetIdFromItemName(SceneObjectPart part, string name, int type) + { + TaskInventoryItem item = part.Inventory.GetInventoryItem(name); + + if (item != null && item.Type == type) + return item.AssetID; + else + return UUID.Zero; + } + + /// + /// accepts a valid UUID, -or- a name of an inventory item. + /// Returns a valid UUID or UUID.Zero if key invalid and item not found + /// in prim inventory. + /// + /// Scene object part to search for inventory item + /// + /// + public static UUID GetAssetIdFromKeyOrItemName(SceneObjectPart part, string identifier) + { + UUID key; + + // if we can parse the string as a key, use it. + // else try to locate the name in inventory of object. found returns key, + // not found returns UUID.Zero + if (!UUID.TryParse(identifier, out key)) + { + TaskInventoryItem item = part.Inventory.GetInventoryItem(identifier); + + if (item != null) + key = item.AssetID; + else + key = UUID.Zero; + } + + return key; + } + + + /// + /// Return the UUID of the asset matching the specified key or name + /// and asset type. + /// + /// Scene object part to search for inventory item + /// + /// + /// + public static UUID GetAssetIdFromKeyOrItemName(SceneObjectPart part, string identifier, AssetType type) + { + UUID key; + + if (!UUID.TryParse(identifier, out key)) + { + TaskInventoryItem item = part.Inventory.GetInventoryItem(identifier); + if (item != null && item.Type == (int)type) + key = item.AssetID; + } + else + { + lock (part.TaskInventory) + { + foreach (KeyValuePair item in part.TaskInventory) + { + if (item.Value.Type == (int)type && item.Value.Name == identifier) + { + key = item.Value.ItemID; + break; + } + } + } + } + + return key; + } + } +} \ No newline at end of file diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 8ecb162d52..df1c968991 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -45,6 +45,7 @@ using OpenSim.Region.CoreModules.World.Terrain; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes.Animation; +using OpenSim.Region.Framework.Scenes.Scripting; using OpenSim.Region.Physics.Manager; using OpenSim.Region.ScriptEngine.Shared; using OpenSim.Region.ScriptEngine.Shared.Api.Plugins; @@ -324,43 +325,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } } - protected UUID InventoryKey(string name, int type) - { - TaskInventoryItem item = m_host.Inventory.GetInventoryItem(name); - - if (item != null && item.Type == type) - return item.AssetID; - else - return UUID.Zero; - } - - /// - /// accepts a valid UUID, -or- a name of an inventory item. - /// Returns a valid UUID or UUID.Zero if key invalid and item not found - /// in prim inventory. - /// - /// - /// - protected UUID KeyOrName(string k) - { - UUID key; - - // if we can parse the string as a key, use it. - // else try to locate the name in inventory of object. found returns key, - // not found returns UUID.Zero - if (!UUID.TryParse(k, out key)) - { - TaskInventoryItem item = m_host.Inventory.GetInventoryItem(k); - - if (item != null) - key = item.AssetID; - else - key = UUID.Zero; - } - - return key; - } - // convert a LSL_Rotation to a Quaternion public static Quaternion Rot2Quaternion(LSL_Rotation r) { @@ -1790,7 +1754,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { UUID textureID = new UUID(); - textureID = InventoryKey(texture, (int)AssetType.Texture); + textureID = ScriptUtils.GetAssetIdFromItemName(m_host, texture, (int)AssetType.Texture); if (textureID == UUID.Zero) { if (!UUID.TryParse(texture, out textureID)) @@ -2425,7 +2389,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); // send the sound, once, to all clients in range - m_host.SendSound(KeyOrName(sound).ToString(), volume, false, 0, 0, false, false); + m_host.SendSound(ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound, AssetType.Sound).ToString(), volume, false, 0, 0, false, false); } // Xantor 20080528 we should do this differently. @@ -2443,7 +2407,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (m_host.Sound != UUID.Zero) llStopSound(); - m_host.Sound = KeyOrName(sound); + m_host.Sound = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound, AssetType.Sound); m_host.SoundGain = volume; m_host.SoundFlags = 1; // looping m_host.SoundRadius = 20; // Magic number, 20 seems reasonable. Make configurable? @@ -2463,7 +2427,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (prim.Sound != UUID.Zero) llStopSound(); - prim.Sound = KeyOrName(sound); + prim.Sound = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound, AssetType.Sound); prim.SoundGain = volume; prim.SoundFlags = 1; // looping prim.SoundRadius = 20; // Magic number, 20 seems reasonable. Make configurable? @@ -2475,7 +2439,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (m_host.Sound != UUID.Zero) llStopSound(); - m_host.Sound = KeyOrName(sound); + m_host.Sound = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound, AssetType.Sound); m_host.SoundGain = volume; m_host.SoundFlags = 1; // looping m_host.SoundRadius = 20; // Magic number, 20 seems reasonable. Make configurable? @@ -2498,14 +2462,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); // send the sound, once, to all clients in range - m_host.SendSound(KeyOrName(sound).ToString(), volume, false, 0, 0, true, false); + m_host.SendSound(ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound, AssetType.Sound).ToString(), volume, false, 0, 0, true, false); } public void llTriggerSound(string sound, double volume) { m_host.AddScriptLPS(1); + // send the sound, once, to all clients in range - m_host.SendSound(KeyOrName(sound).ToString(), volume, true, 0, 0, false, false); + m_host.SendSound(ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound, AssetType.Sound).ToString(), volume, true, 0, 0, false, false); } // Xantor 20080528: Clear prim data of sound instead @@ -3384,7 +3349,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (presence != null) { // Do NOT try to parse UUID, animations cannot be triggered by ID - UUID animID = InventoryKey(anim, (int)AssetType.Animation); + UUID animID = ScriptUtils.GetAssetIdFromItemName(m_host, anim, (int)AssetType.Animation); if (animID == UUID.Zero) presence.Animator.AddAnimation(anim, m_host.UUID); else @@ -3406,7 +3371,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (presence != null) { - UUID animID = KeyOrName(anim); + UUID animID = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, anim); if (animID == UUID.Zero) presence.Animator.RemoveAnimation(anim); @@ -4344,7 +4309,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api private void DoLLTeleport(ScenePresence sp, string destination, Vector3 targetPos, Vector3 targetLookAt) { - UUID assetID = KeyOrName(destination); + UUID assetID = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, destination); // The destinaion is not an asset ID and also doesn't name a landmark. // Use it as a sim name @@ -4411,16 +4376,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); // TODO: Parameter check logic required. - UUID soundId = UUID.Zero; - if (!UUID.TryParse(impact_sound, out soundId)) - { - TaskInventoryItem item = m_host.Inventory.GetInventoryItem(impact_sound); - - if (item != null && item.Type == (int)AssetType.Sound) - soundId = item.AssetID; - } - - m_host.CollisionSound = soundId; + m_host.CollisionSound = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, impact_sound, AssetType.Sound); m_host.CollisionSoundVolume = (float)impact_volume; } @@ -5890,10 +5846,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api LSL_Vector bottom_south_west) { m_host.AddScriptLPS(1); + float radius1 = (float)llVecDist(llGetPos(), top_north_east); float radius2 = (float)llVecDist(llGetPos(), bottom_south_west); float radius = Math.Abs(radius1 - radius2); - m_host.SendSound(KeyOrName(sound).ToString(), volume, true, 0, radius, false, false); + m_host.SendSound(ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound, AssetType.Sound).ToString(), volume, true, 0, radius, false, false); } public void llEjectFromLand(string pest) @@ -6329,7 +6286,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api break; case (int)ScriptBaseClass.PSYS_SRC_TEXTURE: - prules.Texture = KeyOrName(rules.GetLSLStringItem(i + 1)); + prules.Texture = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, rules.GetLSLStringItem(i + 1)); break; case (int)ScriptBaseClass.PSYS_SRC_BURST_RATE: @@ -7215,9 +7172,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api UUID sculptId; if (!UUID.TryParse(map, out sculptId)) - { - sculptId = InventoryKey(map, (int)AssetType.Texture); - } + sculptId = ScriptUtils.GetAssetIdFromItemName(m_host, map, (int)AssetType.Texture); if (sculptId == UUID.Zero) return;