diff --git a/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs b/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs index b67de7eb8f..2bd2bad059 100644 --- a/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs @@ -1285,7 +1285,105 @@ namespace OpenSim.Region.Environment.Scenes } } + /// + /// Rez a script into a prim's inventory from another prim + /// + /// + /// + /// + public void RezScript(LLUUID srcId, SceneObjectPart srcPart, LLUUID destId, int pin, int running, int start_param) + { + TaskInventoryItem srcTaskItem = srcPart.GetInventoryItem(srcId); + if (srcTaskItem == null) + { + // error was already logged + return; + } + + SceneObjectPart destPart = GetSceneObjectPart(destId); + + if (destPart == null) + { + m_log.ErrorFormat( + "[PRIM INVENTORY]: " + + "Could not find script for ID {0}", + destId); + return; + } + + if (destPart.ScriptAccessPin != pin) + { + m_log.WarnFormat( + "[PRIM INVENTORY]: " + + "Script in object {0} : {1}, attempted to load script {2} : {3} into object {4} : {5} with invalid pin {6}", + srcPart.Name, srcId, srcTaskItem.Name, srcTaskItem.ItemID, destPart.Name, destId, pin); + // the LSL Wiki says we are supposed to shout on the DEBUG_CHANNEL - + // "Object: Task Object trying to illegally load script onto task Other_Object!" + // How do we should from in here? + return; + } + + TaskInventoryItem destTaskItem = new TaskInventoryItem(); + + destTaskItem.ItemID = LLUUID.Random(); + destTaskItem.CreatorID = srcTaskItem.CreatorID; + destTaskItem.AssetID = srcTaskItem.AssetID; + destTaskItem.GroupID = destPart.GroupID; + destTaskItem.OwnerID = destPart.OwnerID; + destTaskItem.ParentID = destPart.UUID; + destTaskItem.ParentPartID = destPart.UUID; + + destTaskItem.BaseMask = srcTaskItem.BaseMask; + destTaskItem.EveryoneMask = srcTaskItem.EveryoneMask; + destTaskItem.GroupMask = srcTaskItem.GroupMask; + destTaskItem.OwnerMask = srcTaskItem.OwnerMask; + destTaskItem.NextOwnerMask = srcTaskItem.NextOwnerMask; + destTaskItem.Flags = srcTaskItem.Flags; + + if (destPart.OwnerID != srcPart.OwnerID) + { + if (ExternalChecks.ExternalChecksPropagatePermissions()) + { + destTaskItem.OwnerMask = srcTaskItem.OwnerMask & + srcTaskItem.NextOwnerMask; + destTaskItem.GroupMask = srcTaskItem.GroupMask & + srcTaskItem.NextOwnerMask; + destTaskItem.EveryoneMask = srcTaskItem.EveryoneMask & + srcTaskItem.NextOwnerMask; + destTaskItem.BaseMask = srcTaskItem.BaseMask & + srcTaskItem.NextOwnerMask; + destTaskItem.OwnerMask |= 8; // Slam! + } + } + + destTaskItem.Description = srcTaskItem.Description; + destTaskItem.Name = srcTaskItem.Name; + destTaskItem.InvType = srcTaskItem.InvType; + destTaskItem.Type = srcTaskItem.Type; + + // need something like destPart.AddInventoryItemExclusive(destTaskItem); + // this function is supposed to silently overwrite an existing script with the same name + + destPart.AddInventoryItem(destTaskItem); + + if ( running > 0 ) + { + if (ExternalChecks.ExternalChecksCanRunScript(destTaskItem.AssetID, destPart.UUID, destPart.OwnerID)) + { + // why doesn't the start_param propogate? + destPart.StartScript(destTaskItem, start_param); + } + } + + ScenePresence avatar; + + if(TryGetAvatar(srcTaskItem.OwnerID, out avatar)) + { + destPart.GetProperties(avatar.ControllingClient); + } + } + /// /// Called when an object is removed from the environment into inventory. /// diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs b/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs index 1f5f00f4fb..6009206efb 100644 --- a/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs @@ -102,6 +102,7 @@ namespace OpenSim.Region.Environment.Scenes [XmlIgnore] public scriptEvents m_aggregateScriptEvents=0; [XmlIgnore] private LLObject.ObjectFlags LocalFlags = LLObject.ObjectFlags.None; [XmlIgnore] public bool DIE_AT_EDGE = false; + [XmlIgnore] private int m_scriptAccessPin = 0; [XmlIgnore] public bool m_IsAttachment = false; [XmlIgnore] public uint m_attachmentPoint = (byte)0; @@ -211,6 +212,12 @@ namespace OpenSim.Region.Environment.Scenes get { return m_regionHandle; } set { m_regionHandle = value; } } + + public int ScriptAccessPin + { + get { return m_scriptAccessPin; } + set { m_scriptAccessPin = (int)value; } + } public uint GetEffectiveObjectFlags() { diff --git a/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs b/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs index b5a3ad9b9f..05145737a1 100644 --- a/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs +++ b/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs @@ -4660,13 +4660,54 @@ namespace OpenSim.Region.ScriptEngine.Common public void llSetRemoteScriptAccessPin(int pin) { m_host.AddScriptLPS(1); - NotImplemented("llSetRemoteScriptAccessPin"); + + m_host.ScriptAccessPin = pin; } public void llRemoteLoadScriptPin(string target, string name, int pin, int running, int start_param) { m_host.AddScriptLPS(1); - NotImplemented("llRemoteLoadScriptPin"); + bool found = false; + LLUUID destId = LLUUID.Zero; + LLUUID srcId = LLUUID.Zero; + + if (!LLUUID.TryParse(target, out destId)) + { + llSay(0, "Could not parse key " + target); + return; + } + + // target must be a different prim than the one containing the script + if (m_host.UUID == destId) + { + return; + } + + // copy the first script found with this inventory name + foreach (KeyValuePair inv in m_host.TaskInventory) + { + if (inv.Value.Name == name) + { + // make sure the object is a script + if(10 == inv.Value.Type) + { + found = true; + srcId = inv.Key; + break; + } + } + } + + if (!found) + { + llSay(0, "Could not find script " + name); + return; + } + + // the rest of the permission checks are done in RezScript, so check the pin there as well + World.RezScript(srcId, m_host, destId, pin, running, start_param); + // this will cause the delay even if the script pin or permissions were wrong - seems ok + System.Threading.Thread.Sleep(3000); } // remote_data(integer type, key channel, key message_id, string sender, integer ival, string sval)