From 796ae57bea5e7004ac8d41bee2d496d645db81ce Mon Sep 17 00:00:00 2001
From: Justin Clarke Casey
Date: Wed, 9 Jan 2008 15:46:45 +0000
Subject: Prim inventory script saving phase 2. * It is now possible to edit
 and save scripts directly from prim inventories * On saving, the script will
 be restarted in the region * Doesn't appear that it's yet possible to drag
 inventory contents back to agent inventory.  Not quite sure why this is yet -
 the perms all look very permissive.

---
 OpenSim/Region/Environment/Scenes/InnerScene.cs    |   2 +-
 .../Region/Environment/Scenes/Scene.Inventory.cs   |  82 ++++++++++------
 .../Environment/Scenes/Scene.PacketHandlers.cs     |   2 +-
 .../Scenes/SceneObjectGroup.Inventory.cs           |  98 ++++++++++++++++++-
 .../Region/Environment/Scenes/SceneObjectGroup.cs  |   7 +-
 .../Scenes/SceneObjectPart.Inventory.cs            | 107 +++++++++++++++++----
 6 files changed, 241 insertions(+), 57 deletions(-)

(limited to 'OpenSim/Region/Environment/Scenes')

diff --git a/OpenSim/Region/Environment/Scenes/InnerScene.cs b/OpenSim/Region/Environment/Scenes/InnerScene.cs
index 0935b43..8c0ba3c 100644
--- a/OpenSim/Region/Environment/Scenes/InnerScene.cs
+++ b/OpenSim/Region/Environment/Scenes/InnerScene.cs
@@ -433,7 +433,7 @@ namespace OpenSim.Region.Environment.Scenes
                 }
             }
             return returnResult;
-        }
+        }      
 
         public SceneObjectPart GetSceneObjectPart(uint localID)
         {
diff --git a/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs b/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs
index 1a05bd9..db3da48 100644
--- a/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs
@@ -58,7 +58,9 @@ namespace OpenSim.Region.Environment.Scenes
         /// in which the item is to be placed.</param>
         public void AddInventoryItem(IClientAPI remoteClient, InventoryItemBase item)
         {
-            CachedUserInfo userInfo = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId);
+            CachedUserInfo userInfo 
+                = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId);
+            
             if (userInfo != null)
             {
                 userInfo.AddItem(remoteClient.AgentId, item);
@@ -157,28 +159,47 @@ namespace OpenSim.Region.Environment.Scenes
         /// <param name="itemID"></param>
         /// <param name="primID">The prim which contains the item to update</param>
         /// <param name="isScriptRunning">Indicates whether the script to update is currently running</param>
-        /// <param name="data"></param>
-        /// <returns>Asset LLUID created</returns>        
+        /// <param name="data"></param>       
         public void CapsUpdateTaskInventoryScriptAsset(IClientAPI remoteClient, LLUUID itemId,
                                                        LLUUID primId, bool isScriptRunning, byte[] data)
         {
-            // TODO Not currently doing anything with the isScriptRunning bool
+            // Retrieve group
+            SceneObjectPart part = GetSceneObjectPart(primId);
+            SceneObjectGroup group = part.ParentGroup;            
+            if (null == group)
+            {
+                MainLog.Instance.Error(
+                    "PRIMINVENTORY", 
+                    "Prim inventory update requested for item ID {0} in prim ID {1} but this prim does not exist",
+                    itemId, primId);
 
-            MainLog.Instance.Verbose(
-                "PRIMINVENTORY",
-                "Prim inventory script save functionality not yet implemented."
-                + "  remoteClient: {0}, itemID: {1}, primID: {2}, isScriptRunning: {3}",
-                remoteClient, itemId, primId, isScriptRunning);
-
-            // TODO
-            // Retrieve client LLUID
-            // Retrieve sog containing primID
+                return;
+            }
+                        
             // Retrieve item
-            // Create new asset and add to cache
+            TaskInventoryItem item = group.GetInventoryItem(part.LocalID, itemId);
+            if (null == item)
+            {
+                return;
+            }
+            
+            // Create new asset
+            // XXX Hardcoding the numbers is a temporary measure - need an enumeration for this            
+            AssetBase asset =
+                CreateAsset(item.name, item.desc, 10, 10, data);
+            AssetCache.AddAsset(asset);
+                        
             // Update item with new asset
-            // Trigger SOG update (see RezScript)
-            // Trigger rerunning of script (use TriggerRezScript event, see RezScript)
-            // return new asset id
+            item.asset_id = asset.FullID;
+            group.UpdateInventoryItem(item);
+            group.GetProperites(remoteClient);
+            
+            // Trigger rerunning of script (use TriggerRezScript event, see RezScript)           
+            if (isScriptRunning)
+            {
+                group.StopScript(part.LocalID, item.item_id);
+                group.StartScript(part.LocalID, item.item_id);            
+            }
         }
 
         /// <summary>
@@ -268,14 +289,14 @@ namespace OpenSim.Region.Environment.Scenes
                 }
                 else
                 {
-                    MainLog.Instance.Warn(
+                    MainLog.Instance.Error(
                         "AGENTINVENTORY",
                         "Item ID " + itemID + " not found for an inventory item update.");
                 }
             }
             else
             {
-                MainLog.Instance.Warn(
+                MainLog.Instance.Error(
                     "AGENTINVENTORY",
                     "Agent ID " + remoteClient.AgentId + " not found for an inventory item update.");
             }
@@ -290,7 +311,7 @@ namespace OpenSim.Region.Environment.Scenes
                 CachedUserInfo userInfo = CommsManager.UserProfileCacheService.GetUserDetails(oldAgentID);
                 if (userInfo == null)
                 {
-                    MainLog.Instance.Warn("AGENTINVENTORY", "Failed to find user " + oldAgentID.ToString());
+                    MainLog.Instance.Error("AGENTINVENTORY", "Failed to find user " + oldAgentID.ToString());
                     return;
                 }
 
@@ -299,13 +320,13 @@ namespace OpenSim.Region.Environment.Scenes
                     item = userInfo.RootFolder.HasItem(oldItemID);
                     if (item == null)
                     {
-                        MainLog.Instance.Warn("AGENTINVENTORY", "Failed to find item " + oldItemID.ToString());
+                        MainLog.Instance.Error("AGENTINVENTORY", "Failed to find item " + oldItemID.ToString());
                         return;
                     }
                 }
                 else
                 {
-                    MainLog.Instance.Warn("AGENTINVENTORY", "Failed to find item " + oldItemID.ToString());
+                    MainLog.Instance.Error("AGENTINVENTORY", "Failed to find item " + oldItemID.ToString());
                     return;
                 }
             }
@@ -346,7 +367,7 @@ namespace OpenSim.Region.Environment.Scenes
             CachedUserInfo userInfo = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId);
             if (userInfo == null)
             {
-                MainLog.Instance.Warn("AGENTINVENTORY", "Failed to find user " + remoteClient.AgentId.ToString());
+                MainLog.Instance.Error("AGENTINVENTORY", "Failed to find user " + remoteClient.AgentId.ToString());
                 return;
             }
 
@@ -367,13 +388,13 @@ namespace OpenSim.Region.Environment.Scenes
                 }
                 else
                 {
-                    MainLog.Instance.Warn("AGENTINVENTORY", "Failed to find item " + itemID.ToString());
+                    MainLog.Instance.Error("AGENTINVENTORY", "Failed to find item " + itemID.ToString());
                     return;
                 }
             }
             else
             {
-                MainLog.Instance.Warn("AGENTINVENTORY", "Failed to find item " + itemID.ToString() + ", no root folder");
+                MainLog.Instance.Error("AGENTINVENTORY", "Failed to find item " + itemID.ToString() + ", no root folder");
                 return;
             }
         }
@@ -476,7 +497,7 @@ namespace OpenSim.Region.Environment.Scenes
             }
             else
             {
-                MainLog.Instance.Warn(
+                MainLog.Instance.Error(
                     "PRIMINVENTORY", "Inventory requested of prim {0} which doesn't exist", primLocalID);
             }
         }
@@ -484,7 +505,8 @@ namespace OpenSim.Region.Environment.Scenes
         /// <summary>
         /// Remove an item from a prim (task) inventory
         /// </summary>
-        /// <param name="remoteClient"></param>
+        /// <param name="remoteClient">Unused at the moment but retained since the avatar ID might
+        /// be necessary for a permissions check at some stage.</param>
         /// <param name="itemID"></param>
         /// <param name="localID"></param>
         public void RemoveTaskInventory(IClientAPI remoteClient, LLUUID itemID, uint localID)
@@ -492,7 +514,7 @@ namespace OpenSim.Region.Environment.Scenes
             SceneObjectGroup group = GetGroupByPrim(localID);
             if (group != null)
             {
-                int type = group.RemoveInventoryItem(remoteClient, localID, itemID);
+                int type = group.RemoveInventoryItem(localID, itemID);
                 group.GetProperites(remoteClient);
                 if (type == 10)
                 {
@@ -501,7 +523,7 @@ namespace OpenSim.Region.Environment.Scenes
             }
             else
             {
-                MainLog.Instance.Warn(
+                MainLog.Instance.Error(
                     "PRIMINVENTORY",
                     "Removal of item {0} requested of prim {1} but this prim does not exist",
                     itemID,
@@ -752,4 +774,4 @@ namespace OpenSim.Region.Environment.Scenes
             rootPart.ScheduleFullUpdate();
         }
     }
-}
\ No newline at end of file
+}
diff --git a/OpenSim/Region/Environment/Scenes/Scene.PacketHandlers.cs b/OpenSim/Region/Environment/Scenes/Scene.PacketHandlers.cs
index 647fbf4..5a7d4de 100644
--- a/OpenSim/Region/Environment/Scenes/Scene.PacketHandlers.cs
+++ b/OpenSim/Region/Environment/Scenes/Scene.PacketHandlers.cs
@@ -176,7 +176,7 @@ namespace OpenSim.Region.Environment.Scenes
             agentData.AgentID = avatarID;
             agentData.QueryID = RequestID;
             replyPacket.AgentData = agentData;
-            byte[] bytes = new byte[AvatarResponses.Count*32];
+            //byte[] bytes = new byte[AvatarResponses.Count*32];
 
             int i = 0;
             foreach (AvatarPickerAvatar item in AvatarResponses)
diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectGroup.Inventory.cs b/OpenSim/Region/Environment/Scenes/SceneObjectGroup.Inventory.cs
index b72d743..4d25b5d 100644
--- a/OpenSim/Region/Environment/Scenes/SceneObjectGroup.Inventory.cs
+++ b/OpenSim/Region/Environment/Scenes/SceneObjectGroup.Inventory.cs
@@ -60,6 +60,27 @@ namespace OpenSim.Region.Environment.Scenes
             }            
         }
         
+//        /// Start a given script.
+//        /// </summary>
+//        /// <param name="localID">
+//        /// A <see cref="System.UInt32"/>
+//        /// </param>
+//        public void StartScript(LLUUID partID, LLUUID itemID)
+//        {
+//            SceneObjectPart part = GetChildPart(partID);
+//            if (part != null)
+//            {
+//                part.StartScript(itemID);
+//            }
+//            else
+//            {
+//                MainLog.Instance.Error(
+//                    "PRIMINVENTORY",
+//                    "Couldn't find part {0} in object group {1}, {2} to start script with ID {3}",
+//                    localID, Name, UUID, itemID);
+//            }            
+//        }        
+        
         /// <summary>
         /// Start the scripts contained in all the prims in this group.
         /// </summary>
@@ -71,6 +92,27 @@ namespace OpenSim.Region.Environment.Scenes
             }            
         }
         
+        /// Start a given script.
+        /// </summary>
+        /// <param name="localID">
+        /// A <see cref="System.UInt32"/>
+        /// </param>
+        public void StopScript(uint partID, LLUUID itemID)
+        {
+            SceneObjectPart part = GetChildPart(partID);
+            if (part != null)
+            {
+                part.StopScript(itemID);
+            }
+            else
+            {
+                MainLog.Instance.Error(
+                    "PRIMINVENTORY",
+                    "Couldn't find part {0} in object group {1}, {2} to stop script with ID {3}",
+                    partID, Name, UUID, itemID);
+            }            
+        }         
+        
         /// <summary>
         /// 
         /// </summary>
@@ -156,13 +198,63 @@ namespace OpenSim.Region.Environment.Scenes
 
             return false;
         }
+        
+        /// <summary>
+        /// Returns an existing inventory item.  Returns the original, so any changes will be live.
+        /// </summary>
+        /// <param name="primID"></param>
+        /// <param name="itemID"></param>
+        /// <returns>null if the item does not exist</returns>
+        public TaskInventoryItem GetInventoryItem(uint primID, LLUUID itemID)
+        {
+            SceneObjectPart part = GetChildPart(primID);
+            if (part != null)
+            {
+                return part.GetInventoryItem(itemID);
+            }
+            else
+            {
+                MainLog.Instance.Error(
+                    "PRIMINVENTORY",
+                    "Couldn't find prim local ID {0} in prim {1}, {2} to get inventory item ID {3}",
+                    primID, part.Name, part.UUID, itemID);
+            }   
+            
+            return null;
+        }         
+        
+        /// <summary>
+        /// Update an existing inventory item.
+        /// </summary>
+        /// <param name="item">The updated item.  An item with the same id must already exist
+        /// in this prim's inventory</param>
+        /// <returns>false if the item did not exist, true if the update occurred succesfully</returns>
+        public bool UpdateInventoryItem(TaskInventoryItem item)
+        {
+            SceneObjectPart part = GetChildPart(item.ParentPartID);
+            if (part != null)
+            {
+                part.UpdateInventoryItem(item);
+                
+                return true;
+            }
+            else
+            {
+                MainLog.Instance.Error(
+                    "PRIMINVENTORY",
+                    "Couldn't find prim ID {0} to update item {1}, {2}",
+                    item.ParentPartID, item.name, item.item_id);
+            }   
+            
+            return false;
+        }        
 
-        public int RemoveInventoryItem(IClientAPI remoteClient, uint localID, LLUUID itemID)
+        public int RemoveInventoryItem(uint localID, LLUUID itemID)
         {
             SceneObjectPart part = GetChildPart(localID);
             if (part != null)
             {                
-                int type = part.RemoveInventoryItem(remoteClient, localID, itemID);
+                int type = part.RemoveInventoryItem(itemID);
                 
                 // It might seem somewhat crude to update the whole group for a single prim inventory change,
                 // but it's possible that other prim inventory changes will take place before the region 
@@ -177,4 +269,4 @@ namespace OpenSim.Region.Environment.Scenes
             return -1;
         } 
     }
-}
\ No newline at end of file
+}
diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs
index e8d12ff..c623e55 100644
--- a/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs
@@ -375,8 +375,9 @@ namespace OpenSim.Region.Environment.Scenes
 
             foreach (SceneObjectPart part in m_parts.Values)
             {
-                Vector3 partPosition =
-                    new Vector3(part.AbsolutePosition.X, part.AbsolutePosition.Y, part.AbsolutePosition.Z);
+                // Temporary commented to stop compiler warning
+                //Vector3 partPosition =
+                //    new Vector3(part.AbsolutePosition.X, part.AbsolutePosition.Y, part.AbsolutePosition.Z);
                 Quaternion parentrotation =
                     new Quaternion(GroupRotation.W, GroupRotation.X, GroupRotation.Y, GroupRotation.Z);
 
@@ -827,10 +828,8 @@ namespace OpenSim.Region.Environment.Scenes
         /// <returns></returns>
         public bool HasChildPrim(LLUUID primID)
         {
-            SceneObjectPart childPart = null;
             if (m_parts.ContainsKey(primID))
             {
-                childPart = m_parts[primID];
                 return true;
             }
             return false;
diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectPart.Inventory.cs b/OpenSim/Region/Environment/Scenes/SceneObjectPart.Inventory.cs
index 9e2c256..5d197e3 100644
--- a/OpenSim/Region/Environment/Scenes/SceneObjectPart.Inventory.cs
+++ b/OpenSim/Region/Environment/Scenes/SceneObjectPart.Inventory.cs
@@ -144,7 +144,26 @@ namespace OpenSim.Region.Environment.Scenes
                     itemId, Name, UUID);
             }                
             
-        }
+        }        
+        
+        /// <summary>
+        /// Stop a script which is in this prim's inventory.
+        /// </summary>
+        /// <param name="itemId"></param>        
+        public void StopScript(LLUUID itemId)
+        {
+            if (m_taskInventory.ContainsKey(itemId))
+            {
+                m_parentGroup.Scene.EventManager.TriggerRemoveScript(LocalID, itemId);
+            }            
+            else
+            {
+                MainLog.Instance.Error(
+                    "PRIMINVENTORY", 
+                    "Couldn't stop script with ID {0} since it couldn't be found for prim {1}, {2}", 
+                    itemId, Name, UUID);
+            }                            
+        }        
 
         /// <summary>
         /// Add an item to this prim's inventory.
@@ -173,33 +192,85 @@ namespace OpenSim.Region.Environment.Scenes
             
             m_inventorySerial++;
         }
+        
+        /// <summary>
+        /// Returns an existing inventory item.  Returns the original, so any changes will be live.
+        /// </summary>
+        /// <param name="itemID"></param>
+        /// <returns>null if the item does not exist</returns>
+        public TaskInventoryItem GetInventoryItem(LLUUID itemID)
+        {
+            if (m_taskInventory.ContainsKey(itemID))
+            {
+                return m_taskInventory[itemID];
+            }
+            else
+            {
+                MainLog.Instance.Error(
+                    "PRIMINVENTORY",
+                    "Tried to retrieve item ID {0} from prim {1}, {2} but the item does not exist in this inventory",
+                    itemID, Name, UUID);
+            }
+
+            return null;
+        }
+
+        /// <summary>
+        /// Update an existing inventory item.
+        /// </summary>
+        /// <param name="item">The updated item.  An item with the same id must already exist
+        /// in this prim's inventory.</param>
+        /// <returns>false if the item did not exist, true if the update occurred succesfully</returns>
+        public bool UpdateInventoryItem(TaskInventoryItem item)
+        {
+            if (m_taskInventory.ContainsKey(item.item_id))
+            {
+                m_taskInventory[item.item_id] = item;
+                m_inventorySerial++;
+                
+                return true;
+            }
+            else
+            {
+                MainLog.Instance.Error(
+                    "PRIMINVENTORY",
+                    "Tried to retrieve item ID {0} from prim {1}, {2} but the item does not exist in this inventory",
+                    item.item_id, Name, UUID);
+            }   
+            
+            return false;
+        }
 
         /// <summary>
         /// Remove an item from this prim's inventory
         /// </summary>
-        /// <param name="remoteClient"></param>
-        /// <param name="localID"></param>
         /// <param name="itemID"></param>
-        /// <returns>Numeric asset type of the item removed.</returns>
-        public int RemoveInventoryItem(IClientAPI remoteClient, uint localID, LLUUID itemID)
+        /// <returns>Numeric asset type of the item removed.  Returns -1 if the item did not exist
+        /// in this prim's inventory.</returns>
+        public int RemoveInventoryItem(LLUUID itemID)
         {
-            if (localID == LocalID)
+            if (m_taskInventory.ContainsKey(itemID))
             {
-                if (m_taskInventory.ContainsKey(itemID))
+                string type = m_taskInventory[itemID].inv_type;
+                m_taskInventory.Remove(itemID);
+                m_inventorySerial++;
+                if (type == "lsltext")
+                {
+                    return 10;
+                }
+                else
                 {
-                    string type = m_taskInventory[itemID].inv_type;
-                    m_taskInventory.Remove(itemID);
-                    m_inventorySerial++;
-                    if (type == "lsltext")
-                    {
-                        return 10;
-                    }
-                    else
-                    {
-                        return 0;
-                    }
+                    return 0;
                 }
             }
+            else
+            {
+                MainLog.Instance.Error(
+                    "PRIMINVENTORY",
+                    "Tried to remove item ID {0} from prim {1}, {2} but the item does not exist in this inventory",
+                    itemID, Name, UUID);
+            }            
+
             return -1;
         }
 
-- 
cgit v1.1